IntelliJ で JavaFX 11 アプリケーションを開発するための設定
この記事では IntelliJ を用いて JavaFX 11 アプリケーションを開発する場合に、ほぼいつもやらないといけない基本的な設定方法についてまとめています。
IntelliJ で JavaFX11 を使う時の問題点とその理由
IntelliJ には JavaFX 用のプロジェクトテンプレートが用意されています。
これを使うと、アプリケーションのメインのクラスだけでなく、FXML ファイルやそのコントローラクラスがあらかじめ作成されます。
はじめから FXML を使ったコードが少し書いてあるので便利です。ところが、これがこのままでは動かないのです。ビルドもできないし、実行もできません。
JavaFX SDK のインストールと参照が必要
JDK11 以降、 JavaFX は JDK に含まれないことになりました。
このため、JDK11 以降のバージョンを使って JavaFX を利用したアプリケーションを開発する場合には、JDK をインストールするだけではなく、 JavaFX SDK を別途インストールして、開発環境に認識させる必要があります。
こうした事情は、開発環境が IntelliJ である時に限った問題ではありません。
この意味で IntelliJ 固有の問題ではないのですが、 そうはいっても IntelliJ ユーザーとしては、JavaFX アプリケーションのプロジェクトテンプレートを使ってアプリケーションの開発を始めたのに、 そのままではビルドもできないし、(後述のように) ビルドできても実行時にもエラーが発生してしまいます。
実行時の VM オプションの設定が必要
JavaFX がデフォルトの JDK に含まれなくなったことに伴って、実行時にもデフォルトでは JavaFX モジュールの依存関係が認識されないようになりました。
このため、java の実行時のオプション --add-modulesを用いて JavaFX 系のモジュールを指定する必要があります。
コマンドラインからオプションを指定しなければいけないのと同じ理由で、IntelliJ の統合開発環境 (IDE) 内でも、実行時のオプションを指定する必要があります。
このように、現状では、JavaFX のプロジェクトテンプレートを使う時には、少し設定を変更する必要があります。今後は改善されると思いますけどね。
この記事では、JavaFX SDK の設定などの必須項目に加えて、Scene Builder の設定や ControlsFX の設定についても書いておきます。
スクリーンショットは Mac で記載していますが、Windows でも同様の設定で動作します。
JavaFX11 SDK の参照設定
JavaFX11 SDK のインストール
JavaFX11 を使うので、JDK も 11 であることを確認してください。
ここでは Amazon Corretto 11 をインストールしています。
ここでは JavaFX11 SDK は Gluon のウェブサイトからダウンロードしています。
ここでは zip 形式でダウンロードし、/Library/Java/JavaFX/gluon
以下に展開しています。IntelliJ から JavaFX11 SDK の参照設定
JavaFX11 SDK をインストールしたら、IntelliJ のプロジェクト設定にて、依存モジュールとして参照設定します。
メニューから を選択します。
Project Structure の設定ダイアログの左側のペインで、Modules を選択します。次に右側のペインで Dependencies タブを選択します。
表示されたプラスアイコン をクリックして、lib ディレクトリを選択します。
を選択します。 ここで JavaFX11 SDK のインストールディレクトリ以下のこれで JavaFX11 SDK が依存モジュールとして設定されました。
(適用) ボタンをクリックすると、ビルドプロセスが始まります。 メニューから を選択しても良いでしょう。
これでエラーなくビルドできるはずです。
実行時の VM オプションの設定
どんなエラーが発生するのか?
まずは上記設定でビルドが成功したあと、直ちに実行してみて、どんなエラーが出るかみてみましょう。
緑色の矢印 をクリックして実行してみましょう。
すると、次のようにエラーが発生すると思います。
Exception in Application start method java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051) Caused by: java.lang.RuntimeException: Exception in Application start method at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x28461e11) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x28461e11 at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38) at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056) at sample.Main.start(Main.java:13) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) at java.base/java.security.AccessController.doPrivileged(Native Method) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) Exception running application sample.Main
このエラーは Java VM の実行オプション --add-modules を構成することで解決できます。
VM オプションを設定し依存モジュールを取り込む
実行時の VM オプションは、
で設定します。スクリーンショットのようにツールバーから設定しても、
メニューの を選んでも同じです。--module-path オプションと --add-modules オプションを設定します。
の入力欄にて、次のように設定内容を拡大すると、次のようになります。
--module-path の値は JavaFX11 SDK のインストールディレクトリです。
--module-path=... のように = を付けると認識しないので注意してください。空白をあけてパスを書けば OK です。 次の --add-modules の方は = を付けます。
--add-modules の値は使用している JavaFX のモジュールで異なります。
FXML を使用している場合は javafx.fxml が必要です。 コントロールを使う場合は javafx.controls が必要です。カンマ , 区切りで複数指定できます。
JavaFX11 のモジュール名一覧は次のドキュメントを見てください。
以上を設定することで、次のような Hello World とタイトルの記載された空の画面が開くはずです。
Scene Builder の設定
FXML を使って GUI を作成するときには Scene Builder がとても便利です。
Scene Builder は Gluon のサイトからダウンロードできます。JDK のバージョンにあった Scene Builder をダウンロードしてください。ここでは JDK11 を使っていますので、Scene Builder も Scene Builder for Java 11 を使います。
ダウンロードしてインストールしたら、
メニューの メニューから Scene Builder のパスを設定します。これはプロジェクト毎の設定ではなく、IntelliJ の設定になるので一度設定したら二度目以降は同じ設定が使われます。
ControlsFx の設定
ControlsFX は JavaFX で利用できる UI コントロールライブラリです。利用するためには、ControlsFX のサイトから jar ファイルをダウンロードします。
これを Scene Builder と IntelliJ にて参照設定します。
Scene Builder における ControlsFx の参照設定
まず Scene Builder で ControlsFX を使えるように設定します。
sample.fxml を右クリックして、 を選択します。
すると Scene Builder が開きます。(もし開かない場合は Scene Builder のパスが正しく設定されていない可能性があります。)
Scene Builder の画面の左上の方にある設定アイコンをクリックして、
を選びます。表示されたダイアログで
を選択して、ダウンロードした JAR ファイルを選択します。左側に取り込まれるコントロールが表示されるので、内容を確認して
をクリックします。これで、Scene Builder の左側のペインで ControlsFX のコントロールが選択可能になります。
動作確認を兼ねて、試しに Rating コントロールをひとつ配置します。
ファイルを保存して Scene Builder を閉じ、IntelliJ に戻ります。
IntelliJ における ControlsFx の参照設定
この状態ではまだ IntelliJ では ControlsFX を認識していません。このため、FXML ファイルを開くと org.controlsfx.control.Rating というクラスがエラーとなり赤色で表示されています。
メニューの を選択して、依存モジュールに controlsfx を追加しましょう。
JavaFX SDK を追加したのと同様に、
内のプラスアイコン をクリックして、 を選択します。上でダウンロードした jar ファイルを選択します。
、 をクリックしてダイアログを閉じます。
これで ControlsFX が認識されたはずです。
緑色の矢印 をクリックして実行してみましょう。次のように Rating コントロールが表示されれば正常動作しています。
以上、ここでは IntelliJ で JDK11 と JavaFX11 を利用したアプリケーションを開発する際に行う、プロジェクトの設定方法と、便利な Scene Builder や ControlsFX の設定について動作確認方法を含めて紹介しました。