SceneBuilderで独自クラスを使うには

提供: tknotebook
2016年6月24日 (金) 12:45時点におけるNakamuri (トーク | 投稿記録)による版

移動: 案内検索

メインページ>コンピュータの部屋#JavaFX>JavaFX Tips


いずれ改善されるとは思いますが、現在この記事に執筆時点のSceneBuilder(8.2.0)では JDK付属のクラス以外を簡単には扱えません。SceneBuilderが探索するクラスパスを拡張する方法が用意されていないからです。大変不便です。

かつては クラスパスを指定する方法があったらしいのですが、現在では不可能です。

何が問題かというと、例えば ChoiceBox や ComboBox レベルの比較的単純なコントロールでさえ、 少々凝ったことをしようとすると、独自のリストセルクラス、独自のセルファクトリクラスやコンバータークラスが 必要になります。

ChoiceBox や ComboBoxのリスト項目として、String型だけではなく、独自の Enum型などの独自クラスのオブジェクトを セットできるようになっています。

こうしたことをFXMLで記述することは問題なく可能なのですが、FXML内に JDK以外のクラスが混じると、 SceneBuilder で FXMLファイルが開けなくなってしまいます。これは大変困ります。

この記事では、この問題の対処方法を記述します。

カスタムコンポーネントの追加機能

実は SceneBuilder には利用者が独自に開発した JAR や FXML を登録する機能があります。SceneBuilder の左上の部分にカスタムコンポーネントを表示するエリアがあります。

SceneBuilder Library.png

ここに JAR を登録するには下図のメニューから、JAR/FXML Manager を使います。 メニューを選ぶとファイルの選択ダイアログが現れ、JARを登録することができます。

SceneBuilder Jar FXML MANAGER.png

ここで登録した JAR は

C:\Users\<ユーザ名>\AppData\Roaming\Scene Builder\Library

にコピーされます(Windows版 8.2.0の場合)。

つまりここに SceneBuilder で使いたいクラスが入った JAR を置けばよいわけです。

対処方法

以下の対処方法は Windows の場合です。

まず、JavaFX のアプリをビルドする際、Jarを作るようにします。IntelliJ IDEA では Artifact を追加すればよいですし、Gradleベースのプロジェクトなら最初からJarは作られるようになっているでしょう。

次に、 C:\Users\<ユーザ名>\AppData\Roaming\Scene Builder\Library にその Jar へのシンボリックリンクを置きます。 作成は mklink コマンドがお手軽です。

シンボリックリンクの作成例(IntelliJ IDEA の場合)

cd C:\Users\<ユーザ名>\AppData\Roaming\Scene Builder\Library
mklink Effects.jar C:\javafx_svn_projects\Effects\out\artifacts\Effects_jar\Effects.jar

mklink の実行には管理者権限が必要です。

これで、アプリ独自クラスを含む FXMLファイルが SceneBuilder で開けるようになります。

様々なアプリの Jar が一つのフォルダに混在することになりますが、パッケージ名をきちんと管理していれば クラスが衝突して混乱することはないはずです。

かなり面倒ではありますが、編集できなくなるよりはずっとましです。シンボリックリンクを GUI で簡単に作れる ツールやシェルエクステンションを導入しておくと少しは楽ができると思います。

対処方法 追記

Windows版 8.2.0 では、 C:\Users\<ユーザ名>\AppData\Local\SceneBuilder\app\SceneBuilder.cfg に設定ファイルがあり、クラスパスを設定できます。ここに使いたいクラスのJARのパスを設定すれば 同じことができます。残念ながらクラスファイルのフォルダは指定しても効果ないようです。

いずれにしても、FXMLの中でクラスパスを指定したり、起動オプションでクラスパスを起動できればよいのですが、 未だ発見できてません。

[Application]
app.name=SceneBuilder
app.mainjar=dist.jar
app.version=8.2.0
app.preferences.id=com/oracle/javafx/scenebuilder/app
app.mainclass=com/oracle/javafx/scenebuilder/app/SceneBuilderApp
app.classpath=
app.runtime=$APPDIR\runtime
app.identifier=com.oracle.javafx.scenebuilder.app 

[JVMOptions]

[JVMUserOptions]

[ArgOptions]