ラベル JavaFX追加接続プログラム の投稿を表示しています。 すべての投稿を表示
ラベル JavaFX追加接続プログラム の投稿を表示しています。 すべての投稿を表示

2009年7月2日木曜日

JavaFX 1.2 追加接続プログラム(plug-in)が動くようになった

私は、まだ、NetBeans 6.5を使っています(6.5.1ではありません)。
過日、JavaFX 1.2 SDKとJDK 6 Update 13を導入した際に、NetBeans用の
JavaFX追加接続プログラム(plug-in)もJavaFX 1.2相当のものを導入し直しました。ところが、JavaFXのプログラムを実行しようとすると、誤りが発生して実行できませんでした(見本の一部には実行できるものもありましたが・・・)。
追加接続プログラムに問題があり、その版が更新されれば実行できるようになるだろうと放っておきました。
ところが、本日たまたま古いJDKを整理し、それまで
JDK 6 Update 11で動いていたNetBeans 6.5JDK 6 Update 13で動くようになったところ、JavaFX 1.2のプログラムも正常に実行できるようになりました。
JDKを整理しなくても、
NetBeansの設定変更でうまく対処できるのかもしれません。私のように、「追加接続プログラムの問題だ」とあきらめてしまう前に、一度調べてみると良いかもしれません。
なお、先ごろ公開されたNetBeans 6.7へは、
JavaFX 1.2追加接続プログラムをうまく導入できないようです(NetBeans 6.7の導入ページにも、JavaFXは、NetBeans 6.5.1でのみ利用できまるとなってはいるのですが・・・)。John O'Conner氏が何とかしようと奮闘(?)されているようなのですが。興味のある方は、彼のBlogをご覧ください。

2008年12月24日水曜日

JavaFX追加接続の下見機能でWYSIWYG開発が可能に

ちょっと古めかしい言葉を出してしまいましたが、MSのVisual StudioやNetBeansのMatisseのようなWYSIWYG環境でのソフトウェ開発が、JavaFXでも可能になりました。
それは、NetBeansなどのIDE用に提供されている、JavaFX追加接続(plug-in)プログラムの下見(preview)機能を利用した開発のことです。Visual StudioやMatisseのような、直接操作方式ではありませんが、編集作業と並行して実行時の姿が実時間で見られるので、かなり開発効率が上がります。
事前評価(preview)版のJavaFX追加接続にもその原型はあったのですが、原始コードの編集領域を分割して表示するため編集領域が狭くなる、コードによってはうまく表示ができないなど、正直言って「今一」の感が否めませんでした。しかし、JavaFX 1.0対応版では、これらの点かなり改善さているようです(まだ、それほど試した訳ではないので、問題点の有無を把握し切れてはいませんが)。
少なくとも、下見画面がIDEの窓とは独立した専用の窓に表示されるため、編集領域が狭くなることはありません。
直接操作方式ではありませんが、元々JavaFX言語は宣言型の言語であり、VBやJavaに比べれば、画面表示とコードの対応が取りやすいこともあって、それほど苦にはなりません(もちろん、図形部品をマウスで引っ張りまわして好きな位置に配置したり、寸法を自由に変えられることに越したことはないのですが)。

2008年12月13日土曜日

NetBeans用JavaFX追加接続プログラム日本語表示不具合

JavaFX言語の入門書「JavaFXプログラミング言語の基礎」を書き始め、まだ第1章だけですがWebページで公開しました。
そこに載せている見本コードの動作確認をしていて分かったのですが、NetBeans用JavaFX追加接続プログラム(JavaFX 1.0相当版:JavaFX 1.0バージョン1.4.3、JavaFX SDK for Windowsバージョン1.3.3)の日本語表示には、まだ未修正の不具合があります。
これは、以前の投稿で記したものですが、標準出力に日本語文字列を表示するようなプログラムを一括変換すると誤りが発生するというものです。同じプログラムを、JavaFX 1.0 SDKのjavafxcでコマンド行から一括変換すると正常に変換でき、日本語が表示できます。したがって、Windows上で動作する
NetBeans用JavaFX追加接続プログラムの標準出力への日本語表示に、問題が残っているようです。ちなみに、枠付き窓に日本語が表示できない不具合は、修正されています。
話は変わりますが、以前から、JavaFX言語は、表現力が高いばかりでなく、初心者がプログラミングを習得するのにも適した言語
であると思っています。Java言語ですと、何はともあれ、「class」を定義しなければなりません。そこで、クラスとは何なのかの話をいきなり始めるか、「とりあえず、おまじない(?)と思って記述してください」と、クラスに関する説明を後回しにするかの選択をしなければなりません。
いずれにしても、説明する方も、また説明される方もあまりすっきりしません。
その点、JavaFXなら、println()関数の説明をするぐらいで「Hello world!」プログラムが書けますので、話が簡単です。また、JavaFX 1.0では、データ型の推定機能が復活しましたので、その点でもプログラミングが楽になります。しかも、動画や多重媒体応用プログラムが簡潔に書けるまでになります。
「JavaFX言語でプログラミングを学ぶ」といった講座が一般的になる、そんな日が早く来るといいのですが。

2008年9月9日火曜日

仕立て節がうまく機能しない

前回の投稿で、SCADA UIプログラム例をPAC類型に基づいて構成しなおしました。
そこで、
SCADA UIの構成部品(数値指示計や棒図式指示計など)をjavafx.scene.CustomNodeクラスの派生クラスとしてPACエージェント化しようとしたのですが、どうもうまくいきません。
CustomNodeの派生クラスで、新たに関数を定義しているのですが、その関数が思ったように機能してくれません。関数の機能を限定し、「回避策」的なプログラミングを行えば、少なくともこれまでご紹介したSCADA UIプログラム例と同程度の機能を持った仕立て節を作ることは可能です。ですが、せっかく「仕立てる」のですから、あらが目立つようではどうも…。というわけで、もう少し一括変換器の成熟を待つことにしました。
JavaFX言語V1.0における変更点についても、これまでにご紹介したもの以外の変更があるのですが、すでにご紹介した内容についても更なる変更が生じていますので、こちらについても落ち着くのを待ってご紹介したほうが良さそうです。まだ「2008年の秋」は始まったばかりですから…。

2008年8月3日日曜日

SCADA UIプログラム例のJavaFX SDK対応書き換え:残り

SCADA UIプログラム例の残りの部分を、JavaFX SDK対応に書き換えました。
新たな書き換えの要因として、次のものがあります。
・差分が1と異なる列の指定のしかたが、たとえば、[0,20..100]から[0..100 step 20]のように変わった。
・ConfirmDialogがないので、 javafx.application.Dialogに変えた。

SCADA UI構成単位のJavaFXファイルを置き換えて、企画を再構築して実行すると、図のような画面が表示されます。
次に、
SCADA UI構成単位のJavaFXファイルを示します。

/*
* ScadaClientUI.fx
* An example of a User Interface (UI) module of the client-side
* Presentation component for a SCADA application.
*
* Created and modified:
* V 1.0.0 2008/08/01
*/

package client;

import javafx.animation.*;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import java.lang.System;
import client.ScadaClientControl;

/**
* @author terra
*/

var scc: ScadaClientControl = new ScadaClientControl();

/*
* A control compenent for SCADA Data in the UI module.
*/
class ScadaDataControl {
attribute newNumericDatum: Number;
attribute numericData: Number[] = for (i in [0..180]) 0.0;
attribute alarting: Boolean;
attribute schedular: Timeline = Timeline{
repeatCount: Timeline.INDEFINITE
keyFrames: KeyFrame {
time: 200ms
action: function(): Void {
newNumericDatum = scc.receiveData();
delete numericData[0];
insert newNumericDatum into numericData;
if (newNumericDatum > 90.0 and not alarting) {
alarting = true;
scc.startAlarm();
Dialog {
title: "Alarm"
width: 300, height: 60
visible: true
closeAction: function() {
scc.stopAlarm();
alarting = false;
}
stage: Stage {
content: Text {
x: 10, y: 10
textOrigin: TextOrigin.TOP
fill: Color.RED
font: Font {size: 14}
content: "Flow rate exceeded the second upper limit!"
}
}
}
}
}
}
}
function getDisplayColor(value: Number): Color {
var c: Color = Color.GREEN;
if (value > 90.0) {
c = Color.RED;
} else if (value > 75.0) {
c = Color.color(1.0, 0.6, 0.0);
}
return c;
}
}

var sdc = ScadaDataControl {};
sdc.schedular.start();

Frame {
title: "SCADA UI Example"
width: 800, height: 632
visible: true
closeAction: function(): Void {System.exit(0);}
stage: Stage {
width: 800, height: 600
fill: Color.color(0.9, 0.9, 0.9)
content: [
Group {
translateX: 50, translateY: 50
content: [
Rectangle {
width: 55, height: 18
arcWidth: 4, arcHeight: 4
stroke: Color.BLUE, fill: Color.WHITE
},
Text {
x: 4, y: 5
textOrigin: TextOrigin.TOP
fill: bind sdc.getDisplayColor(sdc.newNumericDatum)
font: Font {
name: "Monospaced", size: 14, style: FontStyle.PLAIN
}
content: bind "{%7.2f sdc.newNumericDatum}"
},
Text {
x: 60, y: 6
textOrigin: TextOrigin.TOP
font: Font {
name: "Monospaced", size: 14, style: FontStyle.PLAIN
}
content: "m3/s"
}
]
},
Group {
translateX: 200, translateY: 50
content: [
Rectangle {
width: 60, height: 120
stroke: Color.BLUE, fill: Color.WHITE
},
Rectangle {
x: 10, y: 10
width: 10, height: 100
fill: LinearGradient {
startX: 0.0, startY: 0.0
endX: 0.0, endY: 1.0
stops: [
Stop {offset: 0.05, color: Color.RED},
Stop {offset: 0.0875, color: Color.color(1.0, 0.6, 0.0)},
Stop {offset: 0.125, color: Color.LIMEGREEN},
]
}
},
Rectangle {
x: 10, y: 10
width: 10, height: bind 50 - sdc.newNumericDatum / 2
fill: Color.BLACK
},
Line {
startX: 23, startY: 10
endX: 23, endY: 110
stroke: Color.BLACK
},
Group {
translateX: 23, translateY: 10
content: for (i in [-100..100 step 50]) Line {
translateY: i / 2 + 50
startX: 0, startY: 0
endX: 3, endY: 0
stroke: Color.BLACK
}
},
Group {
translateX: 32, translateY: 10
content: for (i in [-100..100 step 50]) Text {
translateY: 53 - i / 2
content: "{i}"
font: Font {
name: "Monospaced", size: 10, style: FontStyle.PLAIN
}
horizontalAlignment: HorizontalAlignment.LEADING
verticalAlignment: VerticalAlignment.TOP
}
}
]
},
Group {
translateX: 50, translateY: 200
content: [
Rectangle {
width: 230, height: 120
stroke: Color.BLUE, fill: Color.WHITE
},
Rectangle {
x: 10, y: 22
width: 181, height: 88
fill: Color.BLACK
},
Rectangle {
x: 10, y: 15
width: 181, height: 7
fill: Color.GRAY
},
Rectangle {
x: 10, y: 10
width: 181, height: 5
fill: Color.DARKGRAY
},
Line {
startX: 194, startY: 10
endX: 194, endY: 110
stroke: Color.BLACK
},
Group {
translateX: 194, translateY: 10
content: for (i in [-100..100 step 50]) Line {
translateY: i / 2 + 50
startX: 0, startY: 0
endX: 3, endY: 0
stroke: Color.BLACK
}
},
Group {
translateX: 203, translateY: 11
content: for (i in [-100..100 step 50]) Text {
translateY: 53 - i / 2
content: "{i}"
font: Font {
name: "Monospaced", size: 10, style: FontStyle.PLAIN
}
horizontalAlignment: HorizontalAlignment.LEADING
verticalAlignment: VerticalAlignment.TOP
}
},
Group {
translateX: 10, translateY: 10
content: for (i in [0..179]) Line {
translateX: i
startX: 0, startY: bind 50 - sdc.numericData[i] / 2
endX: 1, endY: bind 50 - sdc.numericData[i + 1] / 2
strokeWidth: 2
stroke: bind sdc.getDisplayColor(sdc.numericData[i + 1])
}
}
]
}
]
}
}

2008年8月2日土曜日

SCADA UIプログラム例のJavaFX SDK対応書き換え:数値指示計


次に、SCADA UIプログラムの例を、JavaFX SDK対応に書き換えてみます。今回は、数値指示計の部分を書き換えました。
逐次解釈型では、
Textオブジェクトで「%m.nf」形式の書式付き出力を行うと、頭の空白文字が無視されという不備な点がありました、それは修正されています。
NetBeansで、JavaFX企画を作成し、SCADA UI構成単位のJavaFXファイルと依頼機を模擬する制御構成単位のJavaファイルを作成し、警報音源ファイルを置いて、企画を構築して実行すると、図のような数値指示計の画面が表示されます。
次に、
SCADA UI構成単位のJavaFXファイルを示します。

/*
* ScadaClientUI.fx
* An example of a User Interface (UI) module of the client-side Presentation
* component for a SCADA application.
*
* Created and modified:
* V 1.0.0 2008/08/01
*/

package client;

import javafx.animation.*;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import java.lang.System;
import client.ScadaClientControl;

/**
* @author terra
*/

var scc: ScadaClientControl = new ScadaClientControl();

/*
* A control compenent for SCADA Data in the UI module.
*/
class ScadaDataControl {
attribute numericData: Number;
attribute schedular: Timeline = Timeline{
repeatCount: Timeline.INDEFINITE
keyFrames: KeyFrame {
time: 200ms
action: function(): Void {
numericData = scc.receiveData();
}
}
}
function getDisplayColor(value: Number): Color {
var c: Color = Color.GREEN;
if (value > 90.0) {
c = Color.RED;
} else if (value > 75.0) {
c = Color.color(1.0, 0.6, 0.0);
}
return c;
}
}

var sdc = ScadaDataControl {};
sdc.schedular.start();

Frame {
title: "SCADA UI Example"
width: 800, height: 632
visible: true
closeAction: function(): Void {System.exit(0);}
stage: Stage {
width: 800, height: 600
fill: Color.color(0.9, 0.9, 0.9)
content: [
Group {
translateX: 50, translateY: 50
content: [
Rectangle {
width: 55, height: 18
arcWidth: 4, arcHeight: 4
stroke: Color.BLUE, fill: Color.WHITE
},
Text {
x: 4, y: 5
textOrigin: TextOrigin.TOP
fill: bind sdc.getDisplayColor(sdc.numericData)
font: Font {name: "Monospaced", size: 14, style: FontStyle.PLAIN}
content: bind "{%7.2f sdc.numericData}"
},
Text {
x: 60, y: 6
textOrigin: TextOrigin.TOP
font: Font {name: "Monospaced", size: 14, style: FontStyle.PLAIN}
content: "m3/s"
}
]
}
]
}
}

また、模擬依頼機制御構成単位のJavaファイルを示します。

/*
* ScadaClientControl.java
* An example of the client-side Control component for a SCADA application.
*
* Created and modified:
* V 1.0.0 2008/07/31
*/

package client;

import java.applet.Applet;
import java.applet.AudioClip;
import javax.swing.JOptionPane;

/**
* @author terra
*/

public class ScadaClientControl {
private AudioClip ac = Applet.newAudioClip(
ScadaClientControl.class.getResource("ALERT.WAV"));
private int i = -1;

/**
* Create and return pseudo SCADA data as if received from a server.
*/
public double receiveData() {
i += 1;
if (i >= 360) {
i = 0;
}
return (double) Math.sin(i * Math.PI / 180) * 100;
}

/**
* Start sounding the alarm.
*/
public void startAlarm() {
ac.loop();
}

/**
* Stop sounding the alarm.
*/
public void stopAlarm() {
ac.stop();
}

/**
* Main method for testing this class.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
ScadaClientControl scc = new ScadaClientControl();

for (int i = 0; i < 5; i++) {
System.out.println(scc.receiveData());
}

scc.startAlarm();
JOptionPane.showMessageDialog(null, "Alarm is sounding!", "Alarm test",
JOptionPane.WARNING_MESSAGE);
scc.stopAlarm();
}
}

2008年7月30日水曜日

目覚まし時計プログラムをJavaFX SDK対応に書き換える


以前に投稿した、目覚まし時計プログラムをJavaFX SDK対応に書き換えてみました。
JavaFX SDKのAPI文書に、Spinnerクラスが見つからなかったので、Sliderクラスに置き換えてみました。また、パッケージ名を「timer」から「clock」に変更しています。
NetBeansで、JavaFX企画を作成し、目覚まし時計プログラムの本体JavaFXファイルと警報鳴動Javaファイルを作成し、警報音源ファイルを置いて、企画を構築して実行すると、図のような画面が表示されます。
次に、
本体の目覚まし時計JavaFXファイルを示します。

package clock;

import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.ext.swing.BorderPanel;
import javafx.ext.swing.Button;
import javafx.ext.swing.Canvas;
import javafx.ext.swing.FlowPanel;
import javafx.ext.swing.GridPanel;
import javafx.ext.swing.Label;
import javafx.ext.swing.Slider;
import javafx.ext.swing.SwingFrame;
import javafx.ext.swing.Slider;
import javafx.ext.swing.TextField;
import javafx.scene.Font;
import javafx.scene.FontStyle;
import javafx.scene.Group;
import javafx.scene.HorizontalAlignment;
import javafx.scene.VerticalAlignment;
import javafx.scene.geometry.Circle;
import javafx.scene.geometry.Line;
import javafx.scene.geometry.Rectangle;
import javafx.scene.layout.VBox;
import javafx.scene.Orientation;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.transform.Translate;
import javafx.scene.transform.Rotate;

import java.lang.Math;
import java.lang.System;
import java.util.Date;

import clock.Sound;

public class Alarm {
private attribute elapsed: Number;
public attribute seconds: Integer = 0;
public attribute minutes: Integer = 0;
public attribute hours: Integer = 0;
public attribute count: Number = 0;
public attribute startTime: Number;
public attribute elapsedTime: Number;
public attribute remainingTime: Number;
public attribute alarmEnabled: Boolean = false;
public attribute running: Boolean = false on replace {
if ((alarmEnabled == true) and (remainingTime <= 0)) {
alarmEnabled = false;
Sound.alarm();
}
};
public attribute timer: Timeline = Timeline {
repeatCount : Timeline.INDEFINITE
keyFrames : KeyFrame {
time: 1s
action: function(): Void {
var now = new Date();
elapsedTime = now.getTime() / 1000 - startTime;
remainingTime = count - elapsedTime;
seconds = remainingTime mod 60 as Integer;
minutes = (remainingTime / 60) mod 60 as Integer;
hours = (remainingTime / 60) / 60 as Integer;
if (elapsedTime >= count) {
timer.stop();
running = false;
hours = 0;
minutes = 0;
seconds = 0;
} else {
running = true;
}
}
}
};
}

SwingFrame {
var alarm = Alarm {}
title: "Alarm Clock"
width: 250
height: 350
visible: true
closeAction: function(): Void {
System.exit(0);
}
content: BorderPanel {
center: Canvas {
content: Group {
var font = Font {
name: "Dialog"
style: FontStyle.PLAIN
size: 15
};
var secs: Number = bind alarm.seconds
var mins: Number = bind alarm.minutes + secs / 60
var hrs: Number = bind alarm.hours + mins / 60
content: [
Rectangle {
width: 250, height: 215
fill: Color.color(0.9, 0.9, 0.9)
},
Circle {
centerX: 120, centerY: 90, radius: 80
fill: Color.WHITE, stroke: Color.BLACK
strokeWidth: 1},
Group {
transform: Translate {x: 120, y: 100}
content: for (i in [1..12]) Text {
var radians = Math.toRadians(30 * i - 90)
transform: Translate {x: 70 * Math.cos(radians),
y: 70 * Math.sin(radians)}
content: "{i}"
horizontalAlignment: HorizontalAlignment.CENTER
verticalAlignment: VerticalAlignment.CENTER
}
},
Group {
transform: [Translate {x: 120, y: 90}]
var hourHand = Line {
startX: 0, startY: 0, endX: 0, endY: -35,
strokeWidth: 4, stroke: Color.BLACK
transform: bind Rotate {angle: hrs * 30, x: 0, y: 0}
}
var minuteHand = Line {
startX: 0, startY: 0, endX: 0, endY: -55,
strokeWidth: 2, stroke: Color.BLUE,
transform: bind Rotate {angle: mins * 6, x: 0, y: 0}
}
var secondHand = Line {
startX: 0, startY: 0, endX: 0, endY: -75,
strokeWidth: 1, stroke: Color.RED,
transform: bind Rotate {angle: alarm.seconds * 6, x: 0, y: 0}
}
content: [hourHand, minuteHand, secondHand]
},
Circle {
centerX: 120, centerY: 90, radius: 3
fill: Color.BLACK, stroke: Color.BLACK
}
]
},
}
bottom: GridPanel {
rows: 4
columns: 1
content: [
FlowPanel {
background: Color.WHITE
content: [
Slider {
minimum: 0, maximum: 11
value: bind alarm.hours with inverse
enabled: bind not(alarm.running)
},
Label {
enabled: bind not(alarm.running)
text: "hour"
}
]
},
FlowPanel {
background: Color.WHITE
content: [
Slider {
minimum: 0, maximum: 59
value: bind alarm.minutes with inverse
enabled: bind not(alarm.running)
},
Label {
enabled: bind not(alarm.running)
text: "min "
}
]
},
FlowPanel {
background: Color.WHITE
content: [
Slider {
minimum: 0, maximum: 59
value: bind alarm.seconds with inverse
enabled: bind not(alarm.running)
},
Label {
enabled: bind not(alarm.running)
text: "sec "
}
]
},
FlowPanel {
background: Color.WHITE
hgap: 40
content: [
Button {
enabled: bind alarm.running
text: "Stop"
action: bind function(): Void {
alarm.running = false;
alarm.timer.stop();
}
},
Button {
enabled: bind not(alarm.running)
text: "Start"
action: function(): Void {
var date = new Date();
alarm.count = alarm.hours * 3600 + alarm.minutes * 60
+ alarm.seconds;
alarm.startTime = date.getTime() / 1000;
alarm.remainingTime = alarm.count;
if (alarm.count != 0) {
alarm.alarmEnabled = true;
alarm.running = true;
alarm.timer.start();
}
}
}
]
}
]
}
}
}

また、次に警報鳴動Javaファイルを示します。

package clock;

import java.applet.Applet;
import java.applet.AudioClip;
import javax.swing.JOptionPane;

public class Sound {
public static void alarm() {
AudioClip ac
= Applet.newAudioClip(Sound.class.getResource("TestMusic.wav"));
ac.loop();
JOptionPane.showMessageDialog(null, "時間ですよ!", "警告!警告!",
JOptionPane.WARNING_MESSAGE);
ac.stop();
}

public static void main(String[] args) {
Sound.alarm();
}
}

上述のJavaFX API文書は、実装されているものとクラス名や属性名が異なっていたり、未実装の機能が存在します。そのため、現状では、多少の試行錯誤が必要です。
また、「The JavaFX™ Script Programming Language Reference (Draft)」の「Chapter 5. Expressions and Operators」に載っている演算子の表は、「JavaFX台本型プログラミング言語基準(草案):第5章」を投稿した後に、変更されています。演算子の剰余は「%」から「mod」に、不等価は「<>」から「!=」になりました。変更があったことについては記されておらず(
、Draft(草案)ですから、仕方ありませんが…)、同ページに載っているコード例では、前の演算子がそのまま使われているので、注意が必要です(「表の方が最新です」と言いたいのですが、「以上」の演算子「>=」が「=>」(動画の補間直定数生成演算子)になっているなど、いくつか誤記があります。…)。

2008年7月26日土曜日

基本的なマウス入力の見本


同じく、NetBeans 6.1用JavaFX追加接続(Plugin)プログラムに付属している見本を参考に、基本的なマウス入力応用プログラムの見本を作ってみました。
実行すると、図のように、マウス指示器の座標と押されたマウス ボタンの番号(一番左のボタンが1。押されていないときは0)が、マウス指示器に追随して表示されます(それ用の画像取り込み用具を使っていないので、肝心のマウス指示器の画像を取り込めていませんが、あしからず)。空色の矩形の中にマウスを移動すると、矩形が半透明で表示されます。
次に、コードを示します。

package deviceInput;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.input.MouseEvent;
import javafx.scene.Group;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextOrigin;
import javafx.scene.transform.Translate;

import java.lang.System;

Frame {
var mouseEvent: MouseEvent;
title: "Mouse Input"
width: 400
height: 332
visible: true
closeAction: function(): Void {
System.exit(0);
}
stage: Stage {
width: 400
height: 300
content: [
Rectangle {
x: 50, y: 50
width: 300, height: 200
fill: Color.LIGHTGRAY
onMousePressed: function(ev: MouseEvent): Void {
mouseEvent = ev;
}
onMouseClicked: function(ev: MouseEvent): Void {
mouseEvent = ev;
}
onMouseReleased: function(ev: MouseEvent): Void {
mouseEvent = ev;
}
onMouseMoved: function(ev: MouseEvent): Void {
mouseEvent = ev;
}
},
Rectangle {
x: 150, y: 100
width: 100, height: 100
fill: Color.SKYBLUE
onMouseEntered: function(ev: MouseEvent): Void {
ev.node.opacity = 0.5;
}
onMouseExited: function(ev: MouseEvent): Void {
ev.node.opacity = 1.0;
}
},
Group {
transform : Translate {x: bind mouseEvent.getX() + 20,
y: bind mouseEvent.getY()}
content : [
Text {
textOrigin: TextOrigin.TOP
fill: Color.RED
content: "StageX:"
},
Text {
translateX: 45
textOrigin: TextOrigin.TOP
fill: Color.RED
content: bind "{mouseEvent.getStageX() as Integer}"
},
Text {
translateX: 80
textOrigin: TextOrigin.TOP
fill: Color.RED
content: "StageY:"
},
Text {
translateX: 125
textOrigin: TextOrigin.TOP
fill: Color.RED
content: bind "{mouseEvent.getStageY() as Integer}"
},
Text {
translateY: 15
textOrigin: TextOrigin.TOP
fill: Color.RED
content: "X:"
},
Text {
translateX: 15, translateY: 15
textOrigin: TextOrigin.TOP
fill: Color.RED
content: bind "{mouseEvent.getX() as Integer}"
},
Text {
translateX: 50, translateY: 15
textOrigin: TextOrigin.TOP
fill: Color.RED
content: "Y:"
},
Text {
translateX: 65, translateY: 15
textOrigin: TextOrigin.TOP
fill: Color.RED
content: bind "{mouseEvent.getY() as Integer}"
},
Text {
translateY: 30
textOrigin: TextOrigin.TOP
fill: Color.RED
content: "Button:"
},
Text {
translateX: 40, translateY: 30
textOrigin: TextOrigin.TOP
fill: Color.RED
content: bind "{mouseEvent.getButton()}"
}
]
}
]
}
}

マウス事象は、その
事象が発生した図式の節(graph node。見本コードでは、Rectangleオブジェクトを使用している)の、事象属性onXxxYyyに定義した呼び戻し関数を用いて取得します。マウス事象から、マウスの座標やボタン開閉器の番号などの情報が得られます。詳しいことは、JavaFX APIを参照してください。
なお、図からもわかりますが、現状(2008/07/23現在の日々構築版追加接続プログラム)では、入力される座標に、一部不具合があるようです。マウス事象が発生した節の原点に対する相対位置を返す関数getX()/getY()は、その節を含むStageの原点に関する相対位置を返すgetStageX()/getStageY()と同じ値を返してしまいます(画面上の絶対位置を返すgetScreenX()/getScreenY()は、正常に機能しています)。

2008年7月19日土曜日

基本的な動画の見本

NetBeans 6.1用JavaFX追加接続(Plugin)プログラムに付属している見本を参考に、基本的な動画応用プログラムの見本を作ってみました。
実行すると、図のような円が色を変えながら左右に往復運動します。
次に、コードを示します。

package motionPicture;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Circle;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;

import java.lang.System;

var x: Integer = 50;
var vx: Integer = 1;
var color: Color = Color.rgb(25, 50, 0);

var timeline: Timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames:
KeyFrame {
time: 10ms
action: function(): Void {
x += vx;
color = Color.rgb((x / 2), x, 0);
if (x < 50) {
vx = 1;
} else if (x > 250) {
vx = -1;
}
}
}
};

timeline.start();

Frame {
title: "Basic Motion"
width: 310
height: 130
visible: true
closeAction: function(): Void {
System.exit(0);
}
stage: Stage {
fill: Color.LIGHTGRAY
content: Circle {
centerX: bind x, centerY: 50, radius: 30
fill: bind color
}
}
}
動画は、前はdur演算子を用いて実現していましたが、JavaFX SDKでは、javafx.animation.Timelineクラスの機能を利用します。
repeatCount属性には、動画の繰り返し回数を、0以上の整数で指定します。無限に繰り返すときは、上記のように、
Timeline.INDEFINITEを指定します。
keyFrames属性には、KeyFrameの列を指定します。
そして、start()関数を呼び出すと、動画が開始します。
また、各KeyFrameのtime属性には、
Timelineの1周期における相対時刻を指定します。
action属性には、
Timelineの各周期で、time属性で指定した時間が経過したときに呼び出される関数を指定します。上記の例では、無名関数で動画処理を定義しています。
以上が、基本的な動画の記述方法の例です。
最後に、ご注意を一言。本当は、枠付き窓の表題は(「Basic Motion」ではなく)日本語で表示したかったのですが、私が利用している、
2008/07/16現在の日々構築版追加接続プログラムでは日本語表示ができません、(標準出力へも表示できません)。「MS932にマップできない」旨の誤り通報文が表示されて構築できなかったり、構築には成功しても、表示は文字化けを起こします
Javaのプログラムからは問題なく日本語表示できるので、JavaFX追加接続プログラムに関連した問題と思われますが、原因は不明です(追加接続プログラム自体の問題なのか、設定上の問題なのかも分かりません)。

2008年7月17日木曜日

NetBeans 6.1用JavaFX追加接続プログラムの更新

最近のJavaFXについては、The JavaFX™ Script Programming Language Reference (Draft)が公開されていることを、以前の投稿でご紹介しました。それと一緒に、「JavaFX API」も最新のものが公開されています。
ただ、このAPI文書はJavaFX SDKに対応したものなので、「The JavaFX™ Script Programming Language Reference (Draft)」文書のコード例で引用されている
javafx.guiパッケージなどは、もう載っていません。
私は、NetBeans 6.1にJavaFX追加接続(Plugin)プログラム(2008/06/15現在の日々構築版)を追加導入して使っていたのですが、導入時点では、JavaFX SDKには対応していませんでした。最近紹介される見本プログラムはJavaFX SDKに対応したものになっていますので、この機会に、最新の追加接続プログラムに更新することにしました。
(NetBeans 6.1とそのJavaFX追加接続プログラムの導入をお考えの方は、、「Downloading and Installing a Developmental Build of JavaFX Script Plugin for NetBeans IDE 6.1」が参考になります。ただし、JDKは、(JDK 5ではなく)JDK 6を導入しておいたほうが良いかも知れません。以前の投稿でも記しましたが、JDK 5では一括変換済みコードが実行できないことがありました。少なくとも、私自身はJDK 5で動作させたことはありません
最新の追加接続プログラム(2008/07/16現在の日々構築版)を入手し、以前行った手順と同じようにして追加接続プログラムを更新しようとしたのですが、パソコンに取り込み済みの追加接続プログラムの更新方法が分かりません(NetBeansにあまり習熟していないので)。しかたなく、すでに導入済みの追加接続プログラムを取り外してから、改めて最新版を導入しなおすことにしました。
更新が済み、NetBeansを再起動すると、作成済みの企画(Project)の名称が朱字で表示され、「参照の問題を解決せよ」なる旨の通報窓が表示されます。指示されように、
基盤(Platform)環境にJavaFX SDK(私の環境では、選択肢に「JavaFX SDK #1」がありましたので、それ)を追加すると、企画名が元の黒字表示に戻り、「参照の問題」が解決したようです