JavaFXであそんでみた.

デビュー前から負け戦のJavaFX.1.0のベータをNetBeansであそんでみた.JavaFXは,JavaVMで動くスクリプト言語の一つ.Javaの豊富なクラスライブラリを直接呼び出すことができる.と,ここまでなら,JythonやらJRubyやら佃煮にするほど同類の言語があるのだが,JavaFXFlash対抗馬を目指して開発されているので,ひと味違う.アニメーションするGUIに特化した言語設計,ライブラリ設計がなされているのだ.

言語の特徴

オブジェクトリテラル

ソースコードを一見してもっとも目立つ特徴はオブジェクトのインスタンスリテラルとして書くことができること.

var f = 
Frame {
	title:"JavaFX sample"
	width:200
	height: 120
	visible: true
};

これは,

var f = new Frame();
f.title = "Frame 2";
f.width = 200;
f.height = 120;
f.visible = true;

これに等しい.この書き方が強力なのは,入れ子構造を持つウィジェットを定義する際に,ウィジェット入れ子構造をそのままリテラル入れ子構造に反映することができるから.GUIを書くときにはかなり見通しがよくなる.

文字列リテラルの中にexpressionが書ける.
var a = "World";
System.out.println("Hello {a}");

とやると

Hello World

と出力される.sh や perlの 「$変数名」みたいなものかと思うかもしれないが,これはそんな生易しいものではない.>||{}||<の中には任意の式が書けるのだ.例えばif文なんかも.

var flag = true;
System.out.println("{if (flag) "true" else "false" }");

いちおう文字列の中なのに,{}の中では"がエスケープなしで使えてるのもすごい.パーザの定義がたいへんだっただろうに.

個人的には文字列の中の「$変数名」が勝手に置換されるのは大嫌いなんだけど,JavaFXのこれは,なんというか突き抜けていて「いっそ爽やか」かもしれない.

バインド

JavaFXを特徴づける超強力な機構がこれ.変数を他の変数や式にバインド(束縛)することで,元の変数の変化に自動的に追従するように指定することができる.

var a = 1;
let b = bind a * 2 ;

System.out.println("{b}");
a = 2;
System.out.println("{b}");

とやると

2
4

となる.つまりaを変更するだけで,aの二倍に束縛したbが自動的に再計算されるのだ.すごい.

これを何に使うかというと,たとえば,GUIウィジェットの自動再配置なんかに使える.

var f = Frame {
	title:"JavaFX sample"
	width: 200
	height: 120
	visible: true
};
f.stage = Stage {
            content: Text {
                x: bind f.width /2 
                y: bind f.height /2
                content: "HelloWorld"
            }
        };

これは,Frameのなかにテキストを書いているだけのサンプルだが,テキストの開始点をFrameの中央になるように調整している.Frameをリサイズすると,自動的にテキストが移動する.Javaでおなじことをやろうと思ったら,resizeをトリガーにして,場所を再計算してrepaintして,と結構面倒なことを書かなければならないが,JavaFXならオートマチックだ.

ちなみにbindによってループみたいな構造ができてデッドロックしたり,解決不能な依存グラフができてしまったりしないか,というような心配をする人もいるかもしれないが,基本的にその心配はないようだ.bindされた変数には直接代入できないので,依存は一方向だけにしか記述できないというのが味噌.

参考リンク