在 init() 中使用 JavaFX Alert 时出现 IllegalStateException,因为不在 FX 应用程序线程上
IllegalStateException when using JavaFX Alert in init() because not on FX application thread
使用 this 方法我正在尝试为我的 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);
}
}
但这会导致警报不显示并生成以下堆栈跟踪(请参阅完整堆栈跟踪 here):
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(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();
});
}
每次我需要做一些与界面中发生的事情没有直接关系的工作时,我都会使用这种方法。
摘自维基:
public static void runLater(Runnable runnable)
Parameters:
runnable - the Runnable whose run method will be executed on the JavaFX Application Thread
使用 this 方法我正在尝试为我的 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);
}
}
但这会导致警报不显示并生成以下堆栈跟踪(请参阅完整堆栈跟踪 here):
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(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();
});
}
每次我需要做一些与界面中发生的事情没有直接关系的工作时,我都会使用这种方法。
摘自维基:
public static void runLater(Runnable runnable)
Parameters:
runnable - the Runnable whose run method will be executed on the JavaFX Application Thread