値の操作を行う
では、配置したButtonにactionを設定して、LabelやTextFieldのテキストを操作してみることにしましょう。旧バージョンでは、こうした場合には「バインド」を使って特定のアトリビュートをモデルクラスに関連付けて操作をしました。が、新バージョンでは、こんな面倒くさい操作は不要です。宣言内に変数を用意しておき、コンポーネントを保管して操作すればいいのです。
package javafxapp;
import javafx.ext.swing.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javax.swing.*;
SwingFrame {
var label:Label;
var field:TextField;
title: "MyApplication"
width: 200
height: 120
closeAction: function() {
java.lang.System.exit(0);
}
visible: true
menus: []
content: BorderPanel {
top: label = Label {
text: "please type!"
font: Font {
name: "Serif"
size: 16
style: FontStyle.BOLD
}
foreground: Color.DARKBLUE
}
center: field = TextField {}
bottom: Button {
text: "Click"
action: function(){
label.text = "you typed '{field.text}'!";
}
}
}
}
テキストを書いてボタンを押すと、メッセージが変わる。 |
ここでは、ボタンを押すと、TextFieldに書かれたテキストを取り出して、新しいメッセージをLabelに表示させています。よく見ると、旧バージョンで使われていたバインドは使われていませんね?
SwingFrameの宣言部分を見ると、最初に「var ~」として変数の宣言が書かれています。旧バージョンでは、このように宣言の中にアトリビュートの指定以外のものを書くことはできませんでしたが、新バージョンではこうした変数宣言などを入れることができるのです。このため、わざわざ必要なアトリビュートをすべてモデルクラスなどにバインドする必要はほとんどなくなります。Javaのクラス定義と同じような感覚で、コンポーネントを保管する変数を用意しておけばよいのです。
新バージョンでは、この他にfunctionの定義なども宣言内に用意することができます。要するに、クラスに配置できるアトリビュートやメソッドなどは、すべて宣言を各段階で追加することができるようになったのですね。これにより、既にあるクラスの内容を更に柔軟に変更し利用できるようになりました。
では、従来通りの「アトリビュートをクラスにバインドするやり方は使えないのか?」と思った人。もちろん、バインド機能はちゃんと新バージョンでもありますから、使うことができます。従来は、いちいちバインド用のモデルクラスを定義し、その中のアトリビュートにバインドする必要がありましたが、新バージョンでは普通の変数に直接値をバインドできるようになりました。これにより、バインドは更に簡単に利用することができるようになるでしょう。
ただし、実際に試してみたところ、「バインドされた変数の値を変更→コンポーネントの値が更新される」という動きは正常に働くのですが、逆に「コンポーネントの値を変更→バインドされた変数の値が更新される」という動きではうまく機能しない例が見られました。このあたりは、もう少し動作を確認してみる必要がありそうです。(あるいは、正式リリースでは問題なく動くようになっているかも知れませんね)