【问题标题】:IllegalStateException when using JavaFX Alert in init() because not on FX application thread在 init() 中使用 JavaFX Alert 时出现 IllegalStateException,因为不在 FX 应用程序线程上
【发布时间】:2020-05-21 15:43:04
【问题描述】:

使用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$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

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

【问题讨论】:

标签: java javafx illegalstateexception


【解决方案1】:

过去,我可以通过将逻辑包装在 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)
参数:
runnable - 将在 JavaFX 应用程序线程上执行其 run 方法的 Runnable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2019-08-10
    • 2013-07-24
    • 1970-01-01
    • 2014-01-31
    相关资源
    最近更新 更多