1. ホーム
  2. javafx-2

[解決済み] JavaFX 2.1: ツールキットは、初期化されていません

2022-02-14 13:34:01

質問

私のアプリケーションはSwingベースです。JavaFXを導入し、セカンダリディスプレイにSceneをレンダリングするように構成したいと思います。 JFrameを使用してJFXPanelを保持することもできますが、JavaFX APIを使用してこれを実現したいと思います。

com.sun.glass.ui.Application のサブクラスを作成して Application.launch(this) を使用すると、起動したスレッドがブロックされるため、オプションとして使用することはできません。

Swing EDTからStageをインスタンス化する際、エラーが発生するのですが。

java.lang.IllegalStateException: Toolkit not initialized

何かご指摘はありますか?


編集部:結論

問題点 : 非自明なSwing GUIアプリケーションは、JavaFXコンポーネントを実行する必要があります。アプリケーションのスタートアップ・プロセスは、依存するサービス・レイヤーを起動した後にGUIを初期化します。

ソリューション

サブクラス JavaFX アプリケーションクラス で、別スレッドで実行させるなど。

public class JavaFXInitializer extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        // JavaFX should be initialized
        someGlobalVar.setInitialized(true);
    }
}

補足:Application.launch()メソッドでは、アプリケーションを起動するために Class<? extends Application> を引数として使用する場合、グローバル変数を使用して、JavaFX環境が初期化されたことを通知する必要があります。

別のアプローチ SwingイベントディスパッチャスレッドでJFXPanelをインスタンス化します。 :

final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        new JFXPanel(); // initializes JavaFX environment
        latch.countDown();
    }
});
latch.await();

この方法を用いると、呼び出し側のスレッドは、JavaFX環境がセットアップされるまで待機します。

お好きな解決策をお選びください。私は、JavaFX環境の初期化を知らせるグローバル変数が必要ないことと、スレッドを無駄にしないことから、2番目の解決策を採用しました。

解決方法は?

解決策が見つかりました。JavaFX Platform.runLaterを起動する前に、Swing EDTからJFXPanelを作成すれば、うまくいきました。 この解決策がどの程度信頼できるかわかりませんが、もし不安定であることがわかれば、JFXPanelとJFrameを選択するかもしれません。

public class BootJavaFX {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JFXPanel(); // this will prepare JavaFX toolkit and environment
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        StageBuilder.create()
                                .scene(SceneBuilder.create()
                                        .width(320)
                                        .height(240)
                                        .root(LabelBuilder.create()
                                                .font(Font.font("Arial", 54))
                                                .text("JavaFX")
                                                .build())
                                        .build())
                                .onCloseRequest(new EventHandler<WindowEvent>() {
                                    @Override
                                    public void handle(WindowEvent windowEvent) {
                                        System.exit(0);
                                    }
                                })
                                .build()
                                .show();
                    }
                });
            }
        });
    }
}