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);
}
}
我正在创建一个富文本控件,它使用 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);
}
}