GroovyFX開発者インタビュー(翻訳)

Jonathan Giles氏の許可を得て翻訳。原文はこちら:
Interview with the developers behind GroovyFX | JavaFX News, Demos and Insight // FX Experience

最近、Groovy言語を使ってより簡単かつ強力にJavaFX 2.0のユーザインタフェースを構築できるGroovyFXプロジェクトを見つけたことは、私にとって喜びでした。このプロジェクトについてあれこれ聞いてみようと、私は主開発者の二人に連絡をとってみることにしました。彼らの快諾を得て、ここにFX Experience初のインタビューをお伝えできることになりました。お楽しみください!

自己紹介をお願いします
Jim Clarke: ここ数年間JavaFXに携わっており、"JavaFX-Developing Rich Internet Applications"の共著者でもあります。
Dean Iverson: バージニア工科大学の交通研究所で働いていて、さまざまなリッチクライアント技術を使っています。JavaFXアーリーアダプタで、"Pro JavaFX Platform"の共著者でもあります。

私の理解では、GroovyFXは、GroovyでのJavaFXの利用をずっとシンプルに(かつ、よりGroovyらしく)してくれるAPIです。でもGroovyFXとは何かという話の前に、まずGroovy自体に対する意見を伺いたいと思います。これはユーザインタフェースを書くのに適した言語でしょうか?なぜ他のJVM言語に比べて、Groovyでユーザインタフェースを書くのが好ましいのでしょうか?
Groovyの良い点は、それが徹底的にJavaの世界で構築された言語であり、Javaプラットフォームとの密接な親和性を維持していることです。クロージャや動的型付けを備え、DSL(ドメイン固有言語)のサポートも容易です。Groovyには開発者の生産性を高めるたくさんの機能があり、より簡潔で表現力の高いコードを書くことができます。また、Spockのような優れたツールにより、Groovyはユニットテスト用にも最適な言語です。

JavaFX 2.0はJavaで書かれています。つまりそのままGroovyで使えるわけです。なぜGroovyFXが必要なのでしょう?単にGroovyでJavaFX 2.0のユーザインタフェースを書くのではなく、GroovyFXを使うメリットは何でしょうか?
Groovyは、Builderパターンによってツリー構造言語をサポートしています。すでにXMLやAnt、Swingをサポートした実装があります。GroovyでSwingベースのUIを持つアプリケーションを作る場合には、SwingBuilderがよく使われます。

GroovyFXは、JavaFXアプリケーションでこのBuilderパターンを活用することに重点を置いています。しかしそれだけではなく、Groovyが持つDSL機能を使って、GroovyベースのJavaFXコードをより書きやすく(そして同じくらい大事なことですが)より読みやすいものにしたいのです。例えば、JavaFXの色は、redやblueといった疑似変数を使って設定することが可能です。SwingBuilderは、Groovyの変数をSwingのJavaBeanプロパティにバインドする、バインディング機能を持っています。私たちはこの概念も取り入れて、GroovyFXにもバインディング機能を持たせています。これによって、次のように書くことができます:

tf = textBox(text: 'Change Me!')
label(text: bind{ tf.text })

これで、ユーザがJavaFXのTextBoxの値を変えれば、JavaFX Labelのテキストも自動的に更新されます。

JavaFXのタイムラインを使った開発を簡単にするためのDSLも提供しています

お二人が開発中のGroovyFXとは一体何なのでしょうか?
GroovyFXの目標は、JavaFXの開発を、Javaで行う場合に比べてよりシンプルかつ簡潔にすることです。これはGroovyが組み込みで備えている数多くの機能によって実現されています。例えば、Groovyのビルダーフレームワークによるツリー構造言語のサポートによって、シーングラフを実際のJavaFXのシーングラフにより近い形で宣言できるようになります。これは、GroovyFXのSceneGraphBuilderオブジェクトによって実現されていて、すべてのControl、Shape、EffectなどのJavaFXオブジェクトがサポートされ、イベントハンドリングにはGroovyのクロージャを使うこともできます。

例えば、マウス/キーイベントの処理にGroovyのクロージャを使うことができます。各JavaFXオブジェクトの属性は、Groovyが持っているメカニズムを使って設定できます。以下のシンプルな例は、JavaFXのツリー構造Stage=>Scene=>Group=>rectangleを示しています。このrectangleは、mouse pressedイベントハンドラと、blendエフェクトを持っています。

GroovyFX.start { primaryStage ->
    def sg = new SceneGraphBuilder(primaryStage);
 
    sg.stage(title: "Blend Effect Demo", width: 420, height: 420, visible: true ) {
        scene(fill: hsb(128, 1.0, 1.0, 0.5) ) {
            rectangle(width: 400, height: 400) {
                onMousePressed (onEvent: {e -> println "mouse press @" + e.x + "," + e.y })
                blend(mode: "multiply") {
                    topInput() {
                        colorInput(paint: blue, x: 50, y: 50, width: 200, height: 200)
                    }
                    bottomInput() {
                        colorInput(paint: red, x: 150, y: 150, width: 200, height: 200)
                    }
                }
            }
        }
    }
}

http://fxexperience.com/wp-content/uploads/2011/07/BlendEffect.png
アニメーションに使われるJavaFXのTimelineクラスをサポートするため、タイムラインDSLも作りました。以下のコードはこのDSLの例で、"at"キーワードがJavaFXのKeyFrameを、"change"キーワードがKeyValueを表しています。

x = 0;
y = 0;
def tlb = new TimelineBuilder();
def tl = tlb.timeline(cycleCount: 2, onFinished: { Platform.exit()}) {
    at (1.m, onFinished: { println "x = ${this.x}, y = ${this.y}"} ) {
        change (this,"x") {
            to 2.0
            tween  "ease_both"
        }
        change (this,"y") {
             to 125
        }
    }
}
tl.playFromStart();

このDSLは、"1.m"のようなエントリも理解し、これは1分のJavaFX Durationに相当します。さらに、"200.ms"を200ミリ秒、"10.s"を10秒、"1.h"を1時間などにも使えます。

GroovyFXは、JavaFX 2.0 APIのどの程度をカバーしますか?
JavaFX 2.0 APIのよく使われる部分をカバーするのが目標です。これには、すべてのControl、Shape、Chart、MediaやImageオブジェクトが含まれます。さらに、あらゆるエフェクト、ペイント、トランジション、そしてブラウザページを表示する新しいWeb Engine機能へのサポートも提供されます。

GroovyFXは、Groovyでユーザインタフェースを書けるようにすることが目標であり、GroovyFXでは通常のJavaで同等の機能を書く場合に比べ、JavaFX 2.0のインタフェースをずっと簡潔に構築できることはわかりました。これはつまりアプリケーション全体にGroovyFXを使うことを検討するべきということでしょうか、それともGroovyFXはJavaで書かれた既存のバックエンドコード(Swingのような他のUIツールキットで書かれたユーザインタフェースもすでにあるかもしれません)とうまく組み合わせることが可能なのでしょうか?どんなやり方がお勧めですか?
アプリケーション全体をGroovyで書き、UIのコーディングにGroovyFXを使うことができます。この場合、Griffonのようなフレームワークをチェックしてみると良いでしょう。現在、さまざまなGriffonプラグインがあり、その中にはGriffonでJavaFXアプリを作れるようにするプラグインの原型も存在しています。こういったプラグインでは、ビューコードを書くときにGroovyFXを活用できるでしょう。

Swingとの統合については、何の問題もありません!以下は、Swingアプリケーションを表示するGroovyFXプロジェクトの一例です。webコンテンツを表示する、組み込みのJavaFXのWebViewを使ったシンプルなwebブラウザです。

import groovyx.javafx.SceneGraphBuilder
import groovyx.javafx.GroovyFX;
import javafx.embed.swing.JFXPanel
import groovy.swing.SwingBuilder
import java.awt.BorderLayout as BL
import javax.swing.WindowConstants as WC
import java.awt.Dimension
import javafx.application.Platform;
 
def DEFAULT_URL = "http://www.yahoo.com"
def swing = new SwingBuilder();
def fxPanel = new JFXPanel(preferredSize: new Dimension(800,400));
 
def setUrl = { url ->
    Platform.runLater {
        webEngine.load(url)
    }
}
 
swing.edt {
    frame = frame(title:'Swing Embedded Browser', show: true,
          defaultCloseOperation: WC.EXIT_ON_CLOSE) {
        borderLayout()
        panel(constraints: BL.NORTH) {
            textField(id: "urlField", actionPerformed: {setUrl(urlField.text)}, columns: 40)
            button(text: "Go", actionPerformed: {setUrl(urlField.text)})
        }
        widget(fxPanel, constraints: BL.CENTER)
    }
    frame.pack()
}
 
GroovyFX.start {
     def sg = new SceneGraphBuilder(it);
     fxPanel.scene = sg.scene(width: 800, height: 400) {
         webEngine = webEngine(location: DEFAULT_URL)
         webView(engine: webEngine)
     }
}

http://fxexperience.com/wp-content/uploads/2011/07/SwingBrowser-300x181.png
GroovyFXは比較的新しいプロジェクトですね。GroovyFXの将来の計画を聞かせてください。
すでにJavaFX 2.0の基本的なサポートはできました。次は、これを実際のプロジェクトに使って、さらに簡単かつ直感的な開発ができる方法を探したいと思っています。もちろん、JavaFXが進化するのにあわせて、GroovyFXも進化させていきます。

どのようにしてこのプロジェクトに参加できますか?どんな支援を求めていますか?
とりあえず、ダウンロードして使っていただき、フィードバックをいただきたいと思います。どこが良かったか、どんな機能を追加すべきか、うまく動かないところはどこか、などです。

お時間ありがとうございました。最後に何か付け加えることはありますか?
言うまでもなく、私たちは、Javaで書き直され、新機能が追加されたJavaFX 2.0に興奮しています。GroovyFXは、この勢いの上に、しっかりとしたプラットフォームを提供することで、Groovy開発者がクールな外見を持つアプリケーションを作ることを可能にするものです。