2012年2月5日日曜日

ClojureとFXMLとRuby

この前Clojureで試したのですが、fx:idが使えず微妙な感じでしたが、解決方法を見つけました!

JavaFXではfx:scriptタグというのがありますよね?

このタグにJavaScriptのコードを書いているサンプルコードをよく見ますが、実はこれ、
JavaScript以外でも動くのですよ!

いや、まずJavaScriptが動いているという時点でなにか疑問を持たなければいけなかったのですが。

fx:script

この機能はJSR-223で実現されています。
恐らく。

この機能標準ライブラリにあることを最近知りました。
わざわざダウンロードしていたのは何だったのか・・・・・

fx:scriptを使うためには、言語を指定します。

この時に、FXMLLoaderはgetEngineByNameを使ってスクリプトを実行するためのScriptEngineを取得します。

なので、JSR-223に対応している言語ならば動くのですよ!

とりあえず、安定して動きそうなJRubyを試してみました。

<?xml version="1.0" encoding="UTF-8"?>
<?language ruby?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<fx:script>
def f(e)
e.source.text = 'Action!'
end
</fx:script>
<center>
<Button text="Test" onAction="f($event)" />
</center>
</BorderPane>
view raw root1.xml hosted with ❤ by GitHub

実行



なぜか重いけど動く・・・!

eventはグローバルな変数で、アクションを起こしたい時はこいつを渡しておけばいいようです。

JRubyではgetは書かなくていいし、setも=を使って書けるしなかなか楽ですね。

fx:id

さて、これでfx:idの値を参照してみます。

<?xml version="1.0" encoding="UTF-8"?>
<?language ruby?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<fx:script>
def f
$label.text = 'Action!'
end
</fx:script>
<top>
<Label fx:id="label" text="Test" />
</top>
<center>
<Button text="Test" onAction="f" />
</center>
</BorderPane>
view raw root2.xml hosted with ❤ by GitHub

実行



動いたー!

Clojureで試す

なぜ最初からClojureで動かさなかったのか、それは動かなかったからです。

で動かしてみましょう、ぬるぽが出るはずです。

そこで、"clojure jsr 223"でぐぐってみるとこんなプロジェクトが。
http://code.google.com/p/clojure-jsr223/

そう、clojure標準ではJSR-223に対応していなかったのです。

なのでこのライブラリをdependenciesに追加すれば動くようになります。

<?xml version="1.0" encoding="UTF-8"?>
<?language Clojure?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<BorderPane xmlns:fx="http://javafx.com/fxml">
<top>
<Label fx:id="label" text="Test" />
</top>
<center>
<Button text="Test" onAction="(f)" />
</center>
<fx:script>
(defn f [] (.setText label "Action!"))
</fx:script>
</BorderPane>
view raw root3.xml hosted with ❤ by GitHub

fx:scriptを後ろに置いたのは、labelが見えないと怒られるからです。


これにてこの問題は解決です。

メジャーなScript言語はJavaFXで動くので、是非試してみて下さい。

0 件のコメント:

コメントを投稿