8 SWTとのJavaFX相互運用性
この記事では、JavaFX SceneグラフをStandard Widget Toolkit (SWT)アプリケーションに追加する方法、およびSWTコントロールとJavaFXコントロールを相互運用する方法について説明します。
はじめに
SWTアプリケーションの開発者であれば、オペレーティング・システムのネイティブ・コントロールを使用するSWTを、アニメーションなどの高度なGUI機能を使用するように、容易に構成できないことはご存知でしょう。JavaFXをSWTに統合することによって、SWTアプリケーションを容易に強化できます。必要なものは、javafx.embed.swt
パッケージのFXCanvas
クラスのみです。javafx.embed.swt
パッケージは、JDK_Home/jre/lib/
ディレクトリ内にあるjfxswt.jar
に含まれています。FXCanvasは、SWTキャンバスの表示が可能な任意の場所で使用できる、標準のSWTキャンバスです。それほど単純なことです。
この記事では、図8-1に示すインタラクティブなSWTボタンとJavaFXボタンの作成方法について説明します。
図8-2と図8-3に示すように、ユーザーがいずれかのボタンをクリックすると、もう一方のボタンに表示されるテキストが変化します。この例は、SWTコードとJavaFXコードが相互運用する仕組みを示しています。
SWTコンポーネントへのJavaFXコンテンツの追加
JavaFXでは、JavaFXクラスを作成および操作するJavaコードは、JavaFXユーザー・スレッド内で実行されます。SWTでは、SWTウィジェットを作成および操作するコードは、イベント・ループ・スレッド内で実行されます。JavaFXをSWTに埋め込むと、これら2つのスレッドは同一になります。つまり、一方のツールキットで定義したメソッドをもう一方のツールキットからコールするときの制約がなくなります。
例8-1は、図8-1に示したSWTボタンとJavaFXボタンを作成するためのコードを示しています。コード内に示すように、FXCanvas
クラス内でsetScene()
メソッドを使用して、JavaFXコンテンツをFXCanvas内に設定します。SWTが強制的に新しいJavaFXコンテンツに基づいてキャンバスのレイアウトを行うようにするには、まずJavaFXコンテンツのサイズを変更します。これを行うには、JavaFXコンテンツを含むJavaFXウィンドウを取得し、sizeToScene()
をコールします。JavaFXをSWTに埋め込むと、FXCanvas
の新しい推奨サイズが設定され、これによりSWTは、埋め込まれたJFXコンテンツのサイズを、他のSWTコントロールと同じ方法で変更できるようになります。
JavaFXは、シーン内に配置された階層的なシーン・グラフに従ってコンテンツを構築します。例8-1のコードは、図8-4に示すシーン・グラフを使用して、シーン内にJavaFXボタンを配置しています。このシーン・グラフの説明は、コード例のコメント内に記載されています。
例8-1 プレーンSWTおよびJavaFXボタンのJavaコード
import javafx.embed.swt.FXCanvas; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.paint.Color; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; public class TwoButtons { public static void main(String[] args) { final Display display = new Display(); final Shell shell = new Shell(display); final RowLayout layout = new RowLayout(); shell.setLayout(layout); /* Create the SWT button */ final org.eclipse.swt.widgets.Button swtButton = new org.eclipse.swt.widgets.Button(shell, SWT.PUSH); swtButton.setText("SWT Button"); /* Create an FXCanvas */ final FXCanvas fxCanvas = new FXCanvas(shell, SWT.NONE) { @Override public Point computeSize(int wHint, int hHint, boolean changed) { getScene().getWindow().sizeToScene(); int width = (int) getScene().getWidth(); int height = (int) getScene().getHeight(); return new Point(width, height); } }; /* Create a JavaFX Group node */ Group group = new Group(); /* Create a JavaFX button */ final Button jfxButton = new Button("JFX Button"); /* Assign the CSS ID ipad-dark-grey */ jfxButton.setId("ipad-dark-grey"); /* Add the button as a child of the Group node */ group.getChildren().add(jfxButton); /* Create the Scene instance and set the group node as root */ Scene scene = new Scene(group, Color.rgb( shell.getBackground().getRed(), shell.getBackground().getGreen(), shell.getBackground().getBlue())); /* Attach an external stylesheet */ scene.getStylesheets().add("twobuttons/Buttons.css"); fxCanvas.setScene(scene); /* Add Listeners */ swtButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { jfxButton.setText("JFX Button: Hello from SWT"); shell.layout(); } }); jfxButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { swtButton.setText("SWT Button: Hello from JFX"); shell.layout(); } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } }
ボタンのスタイルは、Jasper Pottsによって執筆された、次の場所にあるブログに基づいています。
http://fxexperience.com/2011/12/styling-fx-buttons-with-css/
IDEでのSWT-JavaFXアプリケーションの作成
IDEでSWT-JavaFXアプリケーションを作成するには、単に次のライブラリをプロジェクトに追加するだけです。
-
swt.jar
。次の場所から入手できるSWTのzipダウンロードに含まれています。
http://eclipse.org/swt
-
jfxswt.jar
。JDK_HOME/jre/lib
ディレクトリ内にあります。-
たとえば、WindowsのデフォルトJDKインストールにおけるフルパスは次のとおりです。
C:\Program Files\Java\jdk1.8.0\jre\lib
-
注意:
環境に応じて、すべてのJARファイルを32ビットまたは64ビットに統一します。
SWT-JavaFXアプリケーションのパッケージ化
SWT-JavaFXアプリケーションのパッケージ化方法は、JavaFXがJDK (7u6以降)にバンドルされているか、別の場所にインストールされている(JDK 7u6より前のリリースの場合)かによって異なります。
JavaFXがJDKにバンドルされている場合のアプリケーションのパッケージ化
NetBeans IDE 7.2以上を使用している場合、「IDEでのSWT-JavaFXアプリケーションの作成」で説明したライブラリを追加すれば、アプリケーションをパッケージ化するための特別な処理は必要ありません。単に「消去してビルド」を実行すると、プロジェクトの/distディレクトリ内に、ダブルクリック可能なJARファイルが生成されます。