チュートリアル > はじめてのJavaFX

はじめてのJavaFX



コンテンツ:


top

はじめに


ただJavaFXのソースコードを眺めているだけではJavaFXを理解することはできません。そこで簡単なJavaFXアプリケーションを作りながらJavaFXについて学びます。

ここでは電卓を作ることを目標にします。電卓を作るために必要なテキストフィールドであったりボタン、ボタンイベント、JavaFXの特徴でもあるトリガーについて紹介します。それでは順番にJavaFXアプリケーションを作っていきましょう!
top

JavaFXの開発環境を整える

ここではeclipseでの設定方法を紹介します。
eclipseの導入についてはチュートリアル/JavaFXの開発環境を整えるを参照して下さい。

  • JavaFXアプリケーションの作成準備
まず、新規プロジェクトからJavaのプロジェクトを作ります。このときプロジェクトの名前などは任意で構いません。又、特に設定をする必要もありません。
次にこのプロジェクトにJavaFXのファイルを追加します。さきほど作ったプロジェクト名の上で右クリックをして「新規」→「その他」をクリックします。そしてその中にあるJavaFX Fileを選択して次へ手順を進めれば完了です。

  • コンパイルする
コンパイル・実行の際は、プログラムの引数にJavaFXのファイル名(xxx.fx)を指定する必要があります。
「構成及び実行」を開いて「JavaFX Application」をダブルクリックします。このときに引数を指定します。例えばHelloWorld.fxというファイルをコンパイル・実行したい場合は以下のような設定になります。

top

JavaFXプログラミング

Hello World


まずは簡単な「Hello,World」アプリケーションを作ってみましょう。 
       import javafx.ui.*;
       
       Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height : 50
       	content : Label{
       		text : "Hello,World"
       	}
       	visible : true
       }
実行例:

top


テキストフィールドの追加


電卓を作る上でテキストフィールドは必要になってきます。さきほどのアプリケーションをテキストフィールドを使って表現してみましょう。
       import javafx.ui.*;
       
       Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height : 50
       	content : TextField{
       		editable : false
       		value : "Hello,World"
       	}
       	visible : true
       }
実行例:

これはさきほどのLabelをTextFieldに置き換えただけですね。ちなみに上記の例でのテキストフィールドはユーザが編集を加えることができません。

top


マルチコンポーネントの利用


電卓にはボタンが必要です、そのためにマルチコンポーネントを追加していきましょう。一般的にGUIの実装では、レイアウトマネージャーを用いてGUIの実装を行います。ここでは単純な例として、シンプルなレイアウトであるFlowLayoutを取り上げます。
JavaFXにはレイアウトに関する便利なクラスが用意されています。例えばFlowLayoutの場合、FlowPanelsというクラスが用意されています。このようにJavaFXではレイアウトに関するクラスは「xxxPanel」という名前規則を持っています。
       import javafx.ui.*;
       
       Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height :100
       	content : FlowPanel{ <--*1
       		content : [
       			TextField {
       				editable : false
       				value : "Hello,World"
       				width : 100
       			},
       			Button{
       				text : "a"
       			},
       			Button{
       				text : "b"
       			},
       			Button{
       				text : "Clear"
       			} <--*2
       		]
       	} <--*1
       	visible : true
       }
実行例:

ここでは複数のコンポーネントを配列を用いて表現しています。配列は、Java同様「[」と「]」で表され、配列の要素は,(カンマ)で区切ることで増やすことができます。また最後の要素にカンマを書くこともできます(*2のところにカンマを書くことができる)。

このサンプルではFlowPanelのcontentに複数のコンポーネントを配置していますが、Frameのcontentにも複数のコンポーネントを配列を用いて表現することができます。しかし、同じ方法ではうまくいきません。まずは*1のところをコメントアウトしてみます。単純にこれでFrameのcontentに複数のコンポーネントを配置したことになりました。これを実行してみましょう。
そうすると想像した結果とは異なったものが出てきたはずです。これはすべてのコンポーネントがFrameのBorderLayout.CENTERに従って重なりあってしまうからです。
top

クリック時のイベント処理


ボタンをクリックしたらなんらかの動作が起こるようにしたいものです。
これを実現するにはボタンにActionListenersのようなものを加える必要があります。

これから先はボタンの動作などの設定なので、GUIの変化がありません。つまり実行例を載せれません。ちょっと味気ないですが我慢して下さいね:D。
また期待した動きをしているかどうかは、System.out.printlnでコンソールに出力される結果を見るか、テキストフィールドの値の変化で確かめてください。
       import javafx.ui.*;
       import java.lang.System; <--*1 
       
       var win = Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height :100
       	content : FlowPanel{
       		content : [
       			TextField {
       				editable : false
       				value : "Hello,World"
       				width : 100
       			},
       			Button{
       				text : "a"
       				action : operation(){
       					System.out.println("'a' clicked");
       				}
       			},
       			Button{
       				text : "b"
       				action : operation(){
       					System.out.println("'b' clicked");
       				}
       			},
       			Button{
       				text : "Clear"
       				action : operation(){
       					System.out.println("'c' clicked");
       				}
       			}
       		]
       	}
       	visible : true
       };
ボタンをクリックしたときのイベント処理は説明する必要がないくらい簡単ですね。クリック時の処理をoperation()の中に書くだけです。しかし、クリックしたときにただコンソールに文字を出力するだけでは電卓も作れません。ここで学んだことだけではまだそれを作ることはできません。

注意することは1つインポートするものが増えたことです(*1)。Java同様にほぼすべてのクラスをインポートする場合はjava.lang.*と表記することもできます。


top

Bindingの実装



JavaFXでは、開発者が自由に新しいクラスを定義したり変数を定義したりすることができます。さきほどの例でも"var win = Frame{..."と変数を使っていました。このことは柔軟なコーディングの助けとなるだけではなく、GUIの実装において、デザインと処理を分離しやすくなります。

Bindingとは自分で定義したデータモデルを自身で利用するための手続きです。これを利用することで変数のいくつかを他の要素に依存させることもできます。例えば、テキストフィールドの値を他の値に依存させることができるのです。ボタンをクリックするとテキストフィールドの値が変化するといった動作もこれを利用します。
       import javafx.ui.*;
       import java.lang.System;
       
       class TextValue{
       	attribute value : String;
       	operation clear(); <--*1
       }
       
       operation TextValue.clear(){ <--*1
       	value = "";
       }
       
       var model = TextValue{ <--*2
       	value : "Hello,Model"
       };
       
       var win = Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height :100
       	content : FlowPanel{
       		content : [
       			TextField {
       				editable : false
       				value : bind model.value <--*3
       				width : 100
       			},
       			Button{
       				text : "a"
       				action : operation(){
       					model.value = model.value.concat("a"); <--*4
       				}
       			},
       			Button{
       				text : "b"
       				action : operation(){
       					model.value = model.value.concat("b"); <--*4
       				}
       			},
       			Button{
       				text : "Clear"
       				action : operation(){
       					model.clear(); <--*5
       				}
       			}
       		]
       	}
       	visible : true
       };
このプログラムには3つの新しい要素が加わっています。
それは、クラスの宣言、メソッドの宣言と変数の宣言です。クラスの宣言ではオブジェクト(attributes)とメソッド(operations)を定義しています。
まず妙に感じるのは*1の部分でしょう。メソッドの宣言部分ではそのメソッドがなんであるかを定義していないからです。そのメソッドがなんであるか、具体的に宣言しているのは「operation TextValue.clear(){...」のところです。

変数の宣言(*2を参照)では新しくTextValueのインスタンスを作り、変数valueの値を"Hello,Model"としています。

テキストフィールドのvalueの値は(*3を参照)前の例とは少し異なっています。テキストフィールドの値を宣言するとき初期値に特定の値を入れてしまいがちですが、model.valueの値を参照したほうがより良いと言えます(直接"Hello,Model"とするのではなく、"Hello,Model"と書かれた値を参照したほうが良い)。
このことは"bind"を使っていることと深く関係しています。ここでbindを用いると、model.valueの値が変化したとき、すぐにその変化をテキストフィールドに反映させることができます。また、Bindingは双方向であることに注意しましょう。もしテキストフィールドが編集可能であったとき、テキストフィールドの値の変化をmodel.valueへ反映させることもできます。

*4のところではaボタンとbボタンを定義し、これらボタンをクリックするとmodel.valueの後ろへ1文字追加('a'もしくは'b')する処理になっています。ここで注意することは文字列の連結です。Javaでは文字列の連結に「+」を使いますが、JavaFXではそれが使えません。くわしくはこちらを参照して下さい。

最後にClearボタンについてですが(*5を参照),さきほどのaボタンやbボタンと基本的なことは同じです。model.valueの文字列を消去する動作を加えるのに、直接「model.value = ""」と書くこともできますが、今回はメソッドの働きを確認したいので、「model.clear()」を用いています。
top

トリガーの追加


まだこのプログラムでは1つ見逃していることがあります。
テキストフィールドの値はいつでも変化させることができますが、その値の変化を知ることはできません。これを解決するには、bind命令を少し書き換えるだけでは実装することはできません。

そこでトリガーという機能の紹介に移りたいと思います、これはJavaFXの特徴ともいうべき機能です。これにより定義したattributeが変化したときなんらかの動作を加えることができます。ここでは単純なトリガーの例を示しますが、トリガーはもっと奥深い機能であること忘れないで下さい。
       import javafx.ui.*;
       import java.lang.System;
       
       class TextValue{
       	attribute value : String;
       	operation clear();
       }
       
       operation TextValue.clear(){
       	value = "";
       }
       
       var model = TextValue{
       	value : "Hello,Model"
       };
       
       trigger on TextValue.value[oldValue] = newValue{ <--*1
       	System.out.println("old:".concat(oldValue).concat("; new:").concat(newValue));
       }
       
       var win = Frame{
       	title : "はじめてのJavaFX"
       	width : 200
       	height :100
       	content : FlowPanel{
       		content : [
       			TextField {
       				editable : false
       				value : bind model.value
       				width : 100
       			},
       			Button{
       				text : "a"
       				action : operation(){
       					model.value = model.value.concat("a");
       				}
       			},
       			Button{
       				text : "b"
       				action : operation(){
       					model.value = model.value.concat("b");
       				}
       			},
       			Button{
       				text : "Clear"
       				action : operation(){
       					model.value = "";
       				}
       			}
       		]
       	}
       	visible : true
       };
ここで変更が加えられたのは*1のところだけです。ここでのトリガーの例はまったく無意味な処理であり、この中は簡単に書き換えることができます。
まずはじめのTextValue.valueの部分でトリガーを付加する場所を示しています。次にあるoldValueでは変化する前の古い値を示しています。そして最後にあるnewvValueでは変化した後の新しい値を示しています。oldValueは任意ですので、変化する前の古い値が必要なければこれを省略することもできます。


本文章はここまです。原文にはSwingのコードも掲載されているので、そちらを参照してみるのもいいかもしれません。
top

&trackback()

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2007年06月11日 06:54
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。