Scenebuilder 拒绝自定义控件中的 Webview

Scenebuilder rejects Webview in custom control

我正在创建一个富文本控件,它使用 WebView 进行显示并使用 HTMLEditor 进行编辑。当我尝试将控件添加到 Scenebuilder 的自定义控件时,抛出了异常:

Exception for: com/spindotta/jfx/control/text/RichTextArea.class

javafx.fxml.LoadException:

at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)

...

Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = LibraryFolderWatcher([library folder location])

...

at javafx.scene.web.WebEngine.checkThread(WebEngine.java:1216)

...

Scenebuilder 似乎尝试实例化 WebView,而 WebView 又尝试实例化 WebEngine,后者似乎需要 FX 应用程序线程,而自定义控件不会生成该线程。

任何 ideas/workaround.

将不胜感激

谢谢!

SceneBuilder 有一个内置机制,可以检查用户库中的所有 jar 以查找自定义控件。

对于任何给定的 jar,这意味着检查其所有 classes,寻找可能的控件:可从 Node 分配的具体 classes。然后它为这些创建一个实例并尝试将其加载到 class 路径上。如果有效,它将被添加到库面板中。

对于包含 WebView 节点的自定义控件,这意味着当 SceneBuilder 检查您的控件时,将完成 WebView 的新实例。此时你会得到你提到的异常:

Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = LibraryFolderWatcher()
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.web.WebEngine.checkThread(WebEngine.java:1216)
at javafx.scene.web.WebEngine.<init>(WebEngine.java:856)
at javafx.scene.web.WebEngine.<init>(WebEngine.java:845)
at javafx.scene.web.WebView.<init>(WebView.java:271)

因此,简单的解决方案是允许自定义控件在由 SceneBuilder 在设计模式下加载时加载到 JavaFX 应用程序线程中。

这个小的自定义控件适合我:

public class WebControl extends StackPane {

    private WebView webView;

    public WebControl() {
        if (Platform.isFxApplicationThread()) {
            init();
        } else {
            // Intended for SceneBuilder
            Platform.runLater(this::init);
        }
    }

    private void init() {
        webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webEngine.load("http://www.google.com");
        getChildren().add(webView);
    }

}