javafxと代替言語 - oracle.comしている。『java ee 7 recipes』 (apress、2013...

9
ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014 JAVA TECH 51 COMMUNITY JAVA IN ACTION ABOUT US blog //rich client / の時代、自由に使える ツールは多いほど良いと 言えます。有利な実装は状況 によって異なるため、ソリュー ションの実装方法を複数知っ ておくことは理にかなっていま す。JavaFX 8 API は優れた API ですが、これだけにとどまらず、 JavaFX アプリケーションの開 発方法を複数知っておくことは 有益です。 本記事では、使えるツール を増やすことができるように、 代替言語で JavaFX アプリケー ションを開発する方法につい て説明します。本記事ではま ず、JavaFX で実装した「お絵 描き」アプリケーションを確 認した後、2 つの代替言語に よる実装と比較します。次に、 Groovy 言語向けの JavaFX API である GroovyFX について確 認します。GroovyFX では、迅 速な JavaFX アプリケーション 開発が重視されています。 注:本記事で紹介するソー ス・コードは GitHub からダウ ンロードできます。 代替言語による JavaFX 開発の 要点 ここでは、特殊な API は利用 せず、数種類の言語の標準機 能のみで単純な JavaFX アプリ ケーションを実装します。 紹介するアプリケーション は、JavaFX 8 で FXML を使用 せずに開発した「お絵描き」 アプリケーションです。このア プリケーションでは、数種類の 色から好きな色を選択し、ペ ンのサイズを変更し、キャンバ スをリセットしてお絵描きをや り直すことができます。このア プリケーションは、ペンの色と サイズを選択するための 2 つ ChoiceBox ノード、絵を描 くキャンバス(Canvas)、およ びキャンバスをリセットするボ タン(Button)で構成されます。 このアプリケーションの実行時 の様子を図1 に示します(す でに才能ある画家が少しスケッ チしています)。 リスト 1 に、JavaFX 8 API を 使用したアプリケーション・コー ド全体を示します。あらゆる JavaFX アプリケーションと同 じく、このアプリケーションも main() メソッドを実行すること で起動(launch)します。また、 start() メソッドには、メインの ステージ(primaryStage)の 作成処理と、大部分のアプリ ケーション実装が含まれます。 特に注目すべきコードとし て、まず Reset ボタン・イベン ト・ハンドラを見てください。 このハンドラはラムダ式で実装 されています。この「Resetボタンをクリックすると、キャ ンバスに描かれた内容が消去 されます。 次に、キャンバスのアクショ ン・リスナーを確認しましょ う。アクション・リスナーも、 JavaFX 8 ではラムダ式で記述 できます。キャンバス上でマウ JavaFXと代替言語 代替言語とカスタムAPIでJavaFXアプリケーションを迅速に開発する JOSH JUNEAU 図1 Java Virtual Machine Josh Juneau:おも に Java、PL/SQL、 Jython/Python を 利用するアプリケー ション開発者、シ ステム・アナリス ト、DBA。Jython Monthly ニュース レター、Jython Podcast、Jython Web サイトを管理 している。『Java EE 7 Recipes』 (Apress、2013 年)、『Introducing Java EE 7』(Apress、 2013 年)の著者。 現在は『Java 8 Recipes』(本年後 半に Apress より出 版予定)を執筆中。

Upload: others

Post on 20-May-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

51

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

今の時代、自由に使えるツールは多いほど良いと

言えます。有利な実装は状況によって異なるため、ソリューションの実装方法を複数知っておくことは理にかなっています。JavaFX 8 API は優れた APIですが、これだけにとどまらず、JavaFXアプリケーションの開発方法を複数知っておくことは

有益です。 本記事では、使えるツールを増やすことができるように、代替言語で JavaFXアプリケーションを開発する方法について説明します。本記事ではまず、JavaFXで実装した「お絵描き」アプリケーションを確認した後、2つの代替言語による実装と比較します。次に、

Groovy 言語向けの JavaFX APIであるGroovyFX について確認します。GroovyFXでは、迅速な JavaFXアプリケーション開発が重視されています。注:本記事で紹介するソース・コードはGitHub からダウンロードできます。

代替言語によるJavaFX 開発の要点ここでは、特殊な API は利用せず、数種類の言語の標準機能のみで単純な JavaFXアプリケーションを実装します。 紹介するアプリケーションは、JavaFX 8で FXMLを使用せずに開発した「お絵描き」アプリケーションです。このアプリケーションでは、数種類の色から好きな色を選択し、ペンのサイズを変更し、キャンバスをリセットしてお絵描きをやり直すことができます。このアプリケーションは、ペンの色とサイズを選択するための 2つの ChoiceBoxノード、絵を描くキャンバス(Canvas)、およびキャンバスをリセットするボ

タン(Button)で構成されます。このアプリケーションの実行時の様子を図 1に示します(すでに才能ある画家が少しスケッチしています)。リスト1に、JavaFX 8 API を使用したアプリケーション・コード全体を示します。あらゆるJavaFXアプリケーションと同じく、このアプリケーションもmain() メソッドを実行することで起動(launch)します。また、start() メソッドには、メインのステージ(primaryStage)の作成処理と、大部分のアプリケーション実装が含まれます。 特に注目すべきコードとして、まず Resetボタン・イベント・ハンドラを見てください。このハンドラはラムダ式で実装されています。この「Reset」ボタンをクリックすると、キャンバスに描かれた内容が消去されます。次に、キャンバスのアクション・リスナーを確認しましょう。アクション・リスナーも、JavaFX 8ではラムダ式で記述できます。キャンバス上でマウ

JavaFXと代替言語代替言語とカスタムAPIでJavaFXアプリケーションを迅速に開発する

JOSH JUNEAU

図1

Java Virtual Machine

Josh Juneau:おもに Java、PL/SQL、Jython/Pythonを利用するアプリケーション開発者、システム・アナリスト、DBA。Jython Monthly ニュースレター、Jython Podcast、Jython Web サイトを管理している。『Java EE 7 Recipes』(Apress、2013年)、『Introducing Java EE 7』(Apress、2013 年)の著者。現在は『Java 8 Recipes』(本年後半にApressより出版予定)を執筆中。

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

52

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

ス・ボタンを押すと、マウス・ボタンを離すまで線が描かれます。

その他のコードはそれほど複雑ではありません。2つの ChoiceBoxコントロールの作成時に、値のリストを含むObservable な配列を設定します。この Buttonコントロールと2つの ChoiceBoxコントロールを1つの HBox 内にグループ化し、このHBoxを BorderPane の上部に追加して、さらにCanvas を BorderPane の中央部に追加します。最後に、このBorderPaneを StackPane に追加してステージを作成します。ステージの構成を完了して可視化する前に、別個の initDraw() メソッドを呼び出してCanvas を初期化します。以下、このアプリケーションをGroovyとJythonで実装した場合の違いを確認しましょう。JavaFX 8とGroovy:ここでは、Groovy 言語で JavaFXDrawアプリケーションを実装します。初めてGroovy に触れる方にご説明すると、Groovyでは Groovy 構文だけでなく標準的な Java 構文も使用でき、熟練した Java 開発者であれば誰でも作業を始めやすい環境が提供されて

います。この点で、Groovy は Java開発者にとって取り掛かりやすい代替言語と言えます。本記事のサンプルでは、Java 構文とGroovy 構文が混在できるという特長を利用します。 リスト2は、Groovy による実装のコード全体です。先ほどの JavaFX 8による実装よりも数行短くなっています。Groovy 構文をもっと利用することもできましたが、JavaとGroovyの混在というメリットを示すために、多くの Java 構文をそのまま使用しました。Groovy に初めて触れる方は、このGroovyアプリケーションもmainメソッド内で起動される点、また、大部分のコードが JavaFX 8 の実装のままである点を確認してください。ただし、セミコロンはGroovyでは必須ではないため省略しています。そのため、JavaFX 版のコードよりも少し簡潔になっています。また、このGroovyコードでは、Java SE 8 のラムダ式ではなくクロージャを使用しています。クロージャとラムダ式の構文は少し異なりますが、全般的な効果は同じです。 次に、Groovy 実装の Resetボタンについて確認し、前述の JavaFX 8 API コードと比較します。この Resetボタンのコードでは、クロージャによりイベント処理の実装をカプセル化します。同様に、キャンバスの「マウス・ボタン押下」イベント・リスナーも、以下のようにGroovy のクロージャを使用して実装しています。

canvas.addEventHandler( MouseEvent.MOUSE_PRESSED, (MouseEvent event) -> { graphicsContext.beginPath(); graphicsContext.moveTo( event.getX(), event.getY()); graphicsContext.stroke();});

すべてのリストのテキストをダウンロード

注:このリストは、紙面の都合上抜粋になっています。省略部分は ... 記号で示しています。コード・リストの全体は、本号のコード・リストをダウンロードしてご確認いただけます。

public class JavaFXDraw extends Application {

public static void main(String[] args) { Application.launch(JavaFXDraw.class, args); } @Override public void start(Stage primaryStage) {

StackPane root = new StackPane(); Screen screen = Screen.getPrimary(); Rectangle2D rect = screen.getVisualBounds(); Canvas canvas = new Canvas(rect.getWidth()/2 + 50, rect.getHeight()/2 + 300 ); final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();

final Button resetButton = new Button("Reset"); resetButton.setOnAction(actionEvent-> { graphicsContext.clearRect(1, 1, graphicsContext.getCanvas().getWidth()-2, graphicsContext.getCanvas().getHeight()-2); }); resetButton.setTranslateX(10);

// Set up the pen color chooser ChoiceBox colorChooser = new ChoiceBox( FXCollections.observableArrayList( "Black", "Blue", "Red", "Green", "Brown", "Orange" ));...

リスト1 リスト2

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

53

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

そのほか、Groovy に関して注意すべき点は次のとおりです。リスト2のコードでは switch 文で int 値を比較していますが、Groovy の switch 文では任意の型の switch 値を比較できます。また、Groovy の switch 文では、case 文で比較する値の型をそろえる必要もありません。Groovy には多数のビルダーがあるため、標準的な Javaよりもオブジェクトの作成が簡単です。Groovyでは、このほかにも多数の機能を利用できます。詳しくは、Groovy のユーザー・ガイドを参照してください。JavaFX 8アプリケーションをGroovyで実装することは簡単です(しかも楽しいものです)。本記事の後半では、さらにGroovyらしくJavaFXを実装する方法を確認します。注:Java SE 8との完全な互換性を確保するためには、Groovy 2.3.x を使用してください。JavaFX 8とJython:Pythonを使用すれば、開発者は何ら支障なく開発を行えると言われています。Pythonのコードは簡潔で、目で追いやす

く、非常に生産的です。Jython は、Pythonを Java 仮想マシン(JVM)向けに実装した言語です。JavaFXアプリケーションを Jythonで実装することは非常に効果的な場合があり、Java 構文の Python 構文への変換は簡単です。注:このサンプルのコードは、Jython 2.7 ベータ版とJavaFX 8で作成しました。リスト3に、前述のお絵描きアプリケーションを Jythonで実装したコード全体を示します。この Jython版コードの行数は、JavaFX 8 やGroovyよりもはるかに少なくなっています。基礎知識として、Jythonでのアプリケーションの起動方法は、これまでのmainメソッドと同じ概念が適用されるものの、少し異なります。Jython のmainメソッドは、JavaFX 8とGroovy の同メソッドと見た目がやや違います。

リスト3に示すように、JythonFXDrawクラスでは JavaFX 標準に基づいてApplication を実装しています。このstartメソッドのロジックは JavaFX および Groovy の実装と同じですが、コードは Python 言語構文で記述されています。 前項と同様に Resetボタンの実装を確認し、他の実装との違いを見ていきましょう。イベント・ハンドラの記述では、resetAction 関数をonActionプロパティに代入していま

す。この resetAction 関数にはキャンバスに描かれた内容を消去するためのロジックが含まれており、そのロジック自体は JavaFX および Groovyの実装と同じです。

同様に、キャンバスのアクション・リスナーを関数として実装し、キャンバスに代入しています。以下に、「mouse_pressed」リスナーの実装コードを示します。

Jythonには switch文がないため、ChoiceBox の選択操作の実装では if文を使用します。

canvas.addEventHandler( MouseEvent.MOUSE_PRESSED, { MouseEvent event-> graphicsContext.beginPath() graphicsContext.moveTo( event.getX(), event.getY()) graphicsContext.stroke() } as EventHandler)

if __name__ == "__main__": ...

Button("Reset", onAction=resetAction)

def mouse_pressed(event): graphics_context. beginPath() graphics_context. moveTo(event.x, event.y) graphics_context. stroke()

すべてのリストのテキストをダウンロード

注:このリストは、紙面の都合上抜粋になっています。省略部分は...記号で示しています。コード・リストの全体は、本号のコード・リストをダウンロードしてご確認いただけます。

class JythonFXDraw(Application):

def start(self, primaryStage): primaryStage.setTitle("JythonFX Draw") root = StackPane() screen = javafx.stage.Screen.getPrimary() rect = screen.visualBounds canvas = Canvas(rect.width/2 + 50, rect.height/2 + 300) graphics_context = canvas.graphicsContext2D def resetAction(event): graphics_context.clearRect(1,1, graphics_context.canvas.width-2, graphics_context.canvas.height-2)...

リスト3

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

54

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

Python に詳しくない方もコードを見てお気づきかもしれませんが、Pythonでは標準のインデント構造に準拠する必要があります。この構造によって、コードは簡潔で読みやすくなっています。Jython に関してほかに注目すべき点は、Groovyと同じく型を宣言する必要がないため、関数のパラメータや変数に型が指定されないことです。

カスタムAPIによるJavaFXアプリケーションの開発前項までに、代替言語で JavaFXアプリケーションを実装することには、さまざまなメリットの可能性があることを確認しました。代替言語でコーディングすること自体にもメリットがありますが、JavaFX に特化した API も使用した場合、さらに多くのメリットが得られます。ここでは、JavaFXアプリケーションの開発方法を根本的に変えるGroovyFX API について確認します。GroovyFX の開発者は、コードの可読性、理解しやすさ、視認性を高め、

シーン・グラフの作成中にその構造を目で確認しやすくしました。 GroovyFX 概要 GroovyFXとは、Groovy ビルダー構文を用いてJavaFXアプリケーションを構築するための APIです。GroovyFXで作成したコードは非常にクリーンで可読性が高いため、JavaFXアプリケーションが構築しやすくなります。しかもGroovyFXでは定型的なコードの多くが不要になるため、個別の API 呼出しに煩わされることなく、本当に実行したい処理の記述に集中できます。定型的なコードが不要となるのは、GroovyFXでは Groovy の強力なドメイン固有言語(DSL)機能と抽象構文ツリー(AST)変換を利用しているためです。それでは、本記事のはじめにGroovyとJythonで作成したアプリケーションを、GroovyFX API を利用するアプリケーションに変換してみます。リスト4は、GroovyFXDrawア

プリケーションのコードです。これまでに見てきた他のコードと比較して、コード量が大幅に減少しました。また、Groovyビルダー・パターンを利用していることから、可読性が向上しています。 そのほかにも、アプリケーションの起動方法が大きく異なります。mainメソッドを定義せず、アプリケーションのプログラミング構造を含む

if idx == 0: new_color = Color.BLACKelif idx == 1: new_color = Color.BLUEelif idx == 2: new_color = Color.RED...

すべてのリストのテキストをダウンロード

注:このリストは、紙面の都合上抜粋になっています。省略部分は ... 記号で示しています。コード・リストの全体は、本号のコード・リストをダウンロードしてご確認いただけます。

import static groovyx.javafx.GroovyFX.startimport groovyx.javafx.beans.FXBindableimport javafx.stage.Screenimport javafx.scene.input.MouseEvent;import javafx.scene.paint.Colorimport javafx.collections.FXCollectionsimport javafx.scene.canvas.Canvasimport javafx.scene.canvas.GraphicsContextimport javafx.stage.Screen

start { stage(title: 'GroovyFX Draw', visible: true) { scene = scene(id: "sc", fill: WHITE, width: Screen.getPrimary() .getVisualBounds().getWidth(), height: Screen.getPrimary() .getVisualBounds().getHeight()) {

canvas = canvas(id: "drawcanvas", width: bind(sc.width()), height: bind(sc.height())) GraphicsContext graphicsContext = canvas.graphicsContext2D canvas.onMousePressed { MouseEvent event-> graphicsContext.beginPath() graphicsContext.moveTo(event.getX(), event.getY()) graphicsContext.stroke() } ...

リスト4

その他のオプションJavaFX 8 APIは優れたAPIですが、これだけにとどまらず、JavaFXアプリケーションの開発方法を複数知っておくことは有益です。

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

55

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

Groovyクロージャを static groovyx.javafx.GroovyFX.start メソッドに単純に渡してアプリケーションを開始しています。

また、コードの構成方法も重要な違いの 1つです。シーン・グラフに埋め込む各ノードを1つの Groovyクロージャとして構成します。さらに、ノード内に別のノードを埋め込んでいるケースもあります。このような視覚的な構文から、ユーザー・インタフェースのレイアウトを簡単に認識できます。GroovyFXでは各ノードのプロパティの指定方法も異なり、プロパティはキーと値のペアとして扱われます。各ノードに固有のプロパティのセットがあり、以下のようにキーと値のペアをカンマで区切って指定できます。

GroovyFXによる開発の開始:GroovyFXを使用するためには、いくつかの簡単な手順を実行する必要があります。GroovyFXを(IDE は使用せずに)任意の環境で使用するためには、最初にGroovyFX のサイトから最新のディストリビューションを用いたGroovyFXをダウンロードし

ます。または、GitHubにあるプロジェクトのクローンを作成することで、ソース・コードからGroovyFXプロジェクトをビルドすることもできます。プロジェクトのクローンを作成するためには、Git をシステムにインストールし、以下のコマンドを実行してプロジェクトのクローンを作成します。

注:Java 8 および JavaFX 8との互換性を確保するためには、GroovyFX 0.4.0 を利用してください。本記事のサンプルは、GroovyFX 0.3.1と Java SE 7 で記述しています(本記事の執筆時点では、GroovyFX 0.4.0 はリリースされていません)。プロジェクトのクローンを作成した後、Gradle を用いてソース・コードからプロジェクトをビルドできます。現時点の最新リリースである0.4.0 では、Java 7 での JavaFX 2.2 の利用または Java 8 での JavaFX 8 の利用がサポートされます。

次に、パッケージに含まれる任意のサンプルを、gradlewコマンドにサンプルの名前を指定して実行でき

ます。たとえば、HelloWorldDemoを実行するためには、以下のコマンドを使用します。

NetBeans などの IDEを使用する場合には、GroovyFXプロジェクトのクローンを作成し、そのクローンをNetBeans 内で開くだけです。デフォルトでは、GroovyFXプロジェクトのディストリビューションはNetBeans IDEプロジェクトです。NetBeans IDE 内で任意のデモを実行するためには、Demo Programsフォルダを展開し、目的のデモを右クリックして「Run」を選択します。このディストリビューションには、優れたGroovyFX サンプルが含まれています。NetBeans 以外の IDEを使用する場合の詳細手順についてはGroovyFX のガイドを参照してください。 基本的なGroovyFXアプリケーションの構築:前述のとおり、すべてのGroovyFXアプリケーションはstaticメソッドの groovyx.javafx.GroovyFX.start で起動します。シーン・グラフを波括弧で囲んで、startメソッドに渡します。このようにGroovy ビルダー構文を利用できますが、内部的にはGroovyFX のSceneGraphBuilder によってシーン・グラフが構成されます。JavaFXコントロールはそれぞれGroovyFXで利用できますが、その構文は通常とは少し異なります。た

とえば、Javaコードで使用する場合、各コントロール名は大文字で始めますが、GroovyFXコードで使用する場合は小文字で始める必要があります。 そのほかにも、Javaでは「setter」を用いてコントロールの各プロパティを設定しますが、GroovyFXでは設定するプロパティのマップ(キーと値のペア)を渡すことができます。 たとえば、JavaFX の Buttonコントロールについて見てみると、JavaFXではコントロールをインスタンス化した後に、Buttonインスタンスのsetterメソッド呼び出して各プロパティを設定する必要があります。一方、GroovyFXでは、以下のようにButtonコントロールを Sceneクロージャ内に配置してインスタンス化し、各プロパティをキーと値のペアとして丸括弧で囲むことで設定します。

イベント・ハンドラはGroovyクロージャとしてインラインで記述してonActionプロパティに代入します。スタイルについても、styleプロパティを用いてインラインで設定します。また、ノード・プロパティの javafx.scene.text.Font に直接アクセスすることもできます。たとえば、前述の

start { // Declare JavaFX // scene graph nodes}

hbox(spacing:10, padding:10) {...

git clone git://github.com/ groovyfx-project/groovyfx.git.

git clone -b 0_4_SNAPSHOT git:// github.com/groovyfx-project/ groovyfx.git

cd <<groovyfx_location>>gradlew build

gradlew HelloWorldDemo

button("Save", style:"-fx-font: 14 arial", onAction: { textEntry = text.getText() println textEntry})

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

56

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

例の styleプロパティでは、スタイルに関するすべての要素を指定しますが、これを以下のように font: '14pt arial'と変更し、フォントのみを指定することもできます。

リスト5に、この Buttonコントロールのほか、TextFieldとLabel のコードを示します。この基本的なアプリケーションでは、テキストを TextField に入力してボタンをクリックすると、そのテキストがサーバーのログ・ファイルに出力されます。非常に単純なアプリケーションですが、GroovyFX による基本的なレイアウトや、HBox の使い方を確認できます。このサンプルのHBoxではラベルとTextField を格納し、間隔のサイズを5に設定しています。

また、色とペイントは、JavaFX のPaint オブジェクトまたは Color オブジェクトを使用するか、擬似カラー

変数(RED、ORANGE、GREEN など)によって設定できます。色は16 進数文字列や JavaFX の CSSスタイルでも定義できます。このように、GroovyFX は非常に柔軟です。GroovyFX には便利なショートカットも多数あります。ショートカットの詳細については、GroovyFX のドキュメントを確認することをお勧めします。インライン・コードの抽出:さらなる

コードをシーン・グラフの外部に配置できます。シーン・グラフ外のコードもスコープ内にはとどまって、シーン・グラフの各ノードから使用できます。リスト6に、コードを整理するために、シーン・グラフの外部にコードを配置した例を示します。リスト6はGroovyFXDrawアプリケーション用のコードですが、Canvas をリセッ

トするための Buttonコントロールについては、イベント・ハンドラのコードを抽出して、シーン・グラフの外部に定義されたクロージャ内に配置しています。このようなGroovyFXアプリケーションのコーディング・スタイルは、多数のイベントを含む大規模なシーン・グラフを扱う場合に非常に便利なことがあります。また、シーン・グラフ内で特定のクラスにアクセスできるようにして、かつそのクラスを同じGroovyファイル内に配置したい場合にも、このスタイルが便利なことがあ

ります。GroovyFXによるプロパティのバインディング:JavaFX のもっとも強力な機能の 1つがバインディング機能です。バインディングにより、シーン・グラフ内のノード間でのリアルタイムのデータ交換やリ操作が可能になります。たとえば、あるTextFieldコン

トロールの textプロパティを特定のLabel にバインドした場合、ユーザーがその TextField に入力を行うと、変更された内容がすべてリアルタイムで Label のテキストに反映されます。JavaFX バインディングには定型的なコードが大量に含まれる場合がありますが、GroovyFX の bind ユー

button("Save", font: '14pt arial', onAction: { textEntry = text.getText() println textEntry})

hbox(spacing: 5){ ...}

すべてのリストのテキストをダウンロード

import static groovyx.javafx.GroovyFX.start

start{ def textEntry; stage(title: "GroovyFX Introduction", width: 600, height: 300, visible: true){ scene(fill: groovyblue){ hbox(spacing: 5){ label("Place Text Here:", textFill: white, halignment: center, valignment: center) text = textField(promptText: "Type here", prefColumnCount: 25) } button("Save", style:"-fx-font: 14 arial", onAction: { textEntry = text.getText() println textEntry }) } }}

リスト5 リスト6

作業が簡単にJavaFX 8を利用すれ

ばアニメーションを簡

単に作成できます。そ

して、GroovyFXを利用

した場合はさらに簡単

になります。

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

57

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

ティリティを使用した場合、そのような定型的なコードが減少します。以下のGroovyFXで記述された Labelは、textという名の TextField にバインドされます。

リスト7に、この技法を用いた単純なバインディングの例を示します。このコードを実行すると、TextFieldに入力されたテキストが Label に反映されます(図 2)。

GroovyFX には、1つのプロパティまたはクラス全体をバインド可能として自動的にマークする@FXBindableという便利なアノテーションもあります。プロパティまたはクラスに@FXBindableアノテーションを付加した場合、実行時にバインディング・ロジックがコードに自動で追加されるため、冗長で定型的なコードを記述する必要がなくなります。 次の例では、車両情報を入力するための単純なフォームが生成されま

Label(text:bind(text, 'text'))

図2

すべてのリストのテキストをダウンロード

String textEntrystart{ stage(title: "GroovyFX Introduction", width: 600, height: 300, visible: true){ scene(fill: groovyblue){ gridPane(hgap: 5, vgap: 10, padding: 20){ hbox(spacing: 5, row:1, columnSpan:2 ){ label("Place Text Here:", textFill: white, halignment: center, valignment: center) text = textField( promptText: "Type here", prefColumnCount: 25) } button("Save", font: "14pt arial", row: 2, column: 1, onAction: { textEntry = text.getText() println textEntry }) label(text: bind(text, 'text'), row: 3, column: 1) } } }}

リスト7

図3

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

58

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

す(図 3)。このフォームの各フィールドは、Car オブジェクト内の各フィールドにバインドされます。このフォームのボタンを押すと、Car オブジェクトのリスト(List)に現在の Car オブジェクトが追加され、現在の List のサイズが自動的にインクリメントされて、フォーム上の Label に表示されます。このサンプルのコードについては、リスト8を参照してください。 GroovyFXによるアニメーション:筆者はおもにエンタープライズ・アプリケーションの開発に従事しているため、アニメーションは得意ではありません。それでも、JavaFX 8 を利用すればアニメーションを簡単に作

成できます。そして、GroovyFXを利用した場合はさらに簡単になります。アニメーションはタイムラインに沿って実行され、そのタイムラインの中でさまざまなアクティビティが発生する可能性があります。 サンプルのタイムラインは、変化する2つの単純な効果で構成され、これらの効果は 1,000ミリ秒の時点から始まり、無限に続きます。このサンプルでは、1つの円と1つの線のアニメーションでヨーヨーに見える動きを生み出します(図4)。円は 1,000ミリ秒ごとに変化し、始点の centerY値(60)から終点の centerY 値(340)へと移動します。同様に、線も1,000

図4

注:このリストは、紙面の都合上抜粋になっています。省略部分は...記号で示しています。コード・リストの全体は、本号のコード・リストをダウンロードしてご確認いただけます。

@FXBindableclass Car{ String make String model String year String description}

@FXBindableclass CarHotel{ List<Car> carList = new ArrayList() Car car = new Car() String carCount def addCar(car){ print "Adding car: ${car.make}" carList.add(car) carCount = "The number of cars is: ${carList.size()}" car = new Car() }

}...

リスト8

すべてのリストのテキストをダウンロード

ORACLE.COM/JAVAMAGAZINE ///////////////////////////// JULY/AUGUST 2014

JAVA TECH

59

COMMUNITY

JAVA IN ACTION

ABOUT US

blog

//rich client /

ミリ秒ごとに変化し、始点の Y値(0)から終点の Y値(280)の間を伸び縮みします。このサンプルをさらに面白くするため、フェード効果のあるテキストを追加しました。このテキストは、指定した時間をかけて不透明度が 0から1に変化します。このサンプル・アニメーションのコードについては、リスト9を参照してください。FXMLのサポート:ビューのコードを FXMLファイル内に配置することは、JavaFXアプリケーションのビジネス・ロジックからビューのコードを分離する方法として推奨されています。GroovyFXでは、シーン・グラフ内で fxmlノードによってFXMLファイルを参照することで、FXML の利用をサポートしています。

その他の代替 APIJRuby や Scala など、JavaFXアプリケーションの開発に利用できる代替言語はほかにもあります。特に JRubyとScala には、それぞれ

JRubyFX、ScalaFXと呼ばれる、JavaFX 開発に特化した独自の API があります。これらの API は、代替言語の構文で JavaFX API を操作するための簡易手法を提供するという点で、GroovyFX に類似しています。詳しくは、各プロジェクトのWebサイトを参照してください。

まとめJavaFX 8 には数々の新機能があり、ラムダ式やストリームといった Java SE 8 のプログラミング構造を利用することで、JavaFX はさらに開発しやすくなります。代替言語には、JavaFX API を超えるメリットが潜んでいます。また、

場合によっては JavaFX APIと密接に連携します。さらに、JavaFX 開発用の独自のDSLを備える代替言語もあり、生産性や使いやすさをさらに向上させることができます。 ぜひ、代替言語を活用した JavaFXアプリケーションの開発方法を学び、新たな JavaFX のツールを手にしてください。</article>

scene {fxml(new File('./myfxml.fxml') .text)...

注:このリストは、紙面の都合上抜粋になっています。省略部分は...記号で示しています。コード・リストの全体は、本号のコード・リストをダウンロードしてご確認いただけます。

import static groovyx.javafx.GroovyFX.startstart { stage(title: "GroovyFX YoYo", width: 500, height: 400, visible: true) { scene(fill: GROOVYBLUE) { circle = circle(centerX: 250, centerY: 60, radius:60, fill: WHITE, stroke: BLACK){ effect: boxBlur(10, 10, 3) } line = line (startX: 250, endX: 250, startY: 0, endY: 0, strokeWidth: 3) myTxt = text("Groovy!", x: 200, y: 150, fill: ORANGE, font: "bold 26pt Arial"){ fade = fadeTransition( duration: 5000.ms, fromValue: 0.0, toValue: 1.0) effect dropShadow(offsetY: 4) } } }...

リスト9

すべてのリストのテキストをダウンロード

LEARN MORE• 『 Introducing GroovyFX:

It’s About Time』• JythonのWebサイト

Java Virtual Machine

MORE ON TOPIC:

FXに特化代替言語で

JavaFXアプリケ

ーションを実装

することには、さ

まざまなメリット

の可能性があり

ます。JavaFXに特化したAPIを

使用した場合、さ

らに多くのメリッ

トが得られます。