在 init() 中使用 JavaFX Alert 时出现 IllegalStateException,因为不在 FX



使用这种方法,我正在尝试为我的JavaFX应用程序实现应用程序预加载器。我想在init()加载一些沉重的东西,这可能会引发异常,然后继续start().为了处理异常,我使用向用户显示一些详细信息的new Alert(AlertType.ERROR).showAndWait();显示警报。

public class Test extends Application {
@Override
public void init() throws Exception {
try {
// dome some heavy stuff here
throw new Exception();
} catch (Exception e) {
new Alert(AlertType.ERROR).showAndWait();
Platform.exit();
}
}
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

但这会导致警报不显示并生成以下堆栈跟踪(请参阅此处的完整堆栈跟踪(:

Exception in Application init method
java.lang.reflect.InvocationTargetException
... 
Caused by: java.lang.RuntimeException: Exception in Application init method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:895)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalStateException: Not on FX application thread; currentThread = JavaFX-Launcher
at javafx.graphics/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:291)
...
at javafx.controls/javafx.scene.control.Alert.<init>(Alert.java:222)
at src/gui.Test.init(Test.java:18)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:824)
... 2 more
Exception running application gui.Test

但是,如果我将 howl 代码从init()移动到start(),我的方法效果很好。

过去,我已经能够通过将逻辑包装在 Platform.runLater(( 调用中来解决此类问题。 即:

try {
[...]
}  catch (Exception e) {
Platform.runLater(new Runnable() {
@Override public void run() {
new Alert(AlertType.ERROR).showAndWait();
Platform.exit();
});
}

每次我需要做一些与界面中发生的事情没有直接关系的工作时,我都会使用这种方法。

取自维基:

公共静态空隙运行稍后(可运行(
参数:
runnable - 运行方法将在 JavaFX 应用程序线程上执行的 Runnable

最新更新