首页 > 解决方案 > JavaFX-任务中的新阶段

问题描述

我想从任务中打开一个新窗口,但由于某种原因Stage stage = new Stage,代码停止执行后,但没有错误。

Task<Void> task = new Task<Void>() {

        @Override protected Void call() throws Exception {

            Parent root = FXMLLoader.load(getClass().getResource("sample2.fxml"));
            Stage stage = new Stage();
            System.out.println("Print");
            stage.setTitle("My New Stage Title");
            stage.setScene(new Scene(root, 100, 100));
            stage.show();
            return null;
        }
    };

它永远不会打印出消息“打印”。

标签: javajavafx

解决方案


回答问题

Task失败的原因是因为您Stage在 JavaFX 应用程序线程以外的线程上创建。Stage各州的 Javadoc :

阶段对象必须在 JavaFX 应用程序线程上构建和修改。

这意味着当您尝试Stage在正在运行的后台线程上创建一个时Task,将导致IllegalStateException一条消息告诉您您不在 JavaFX 应用程序线程上。Stage要解决此问题,请包装在调用中创建和/或修改 a 的所有代码Platform.runLater(Runnable)

旁注:Stage根本不创建in可能会更好TaskFXMLLoader.load(URL)相反,在您的情况下,只需Stage在处理Task.

Task<Parent> task = new Task<Parent>() {
    @Override
    protected Parent call() throws Exception {
        return FXMLLoader.load(getClass().getResource("sample2.fxml"));
    }
};

task.setOnSucceeded(event -> {
    Parent root = task.getValue();
    Stage stage = new Stage();
    stage.setScene(new Scene(root));
    stage.show();
};

为什么没有显示错误?

您说没有错误,但您也没有显示任何会在发生错误时显示错误的代码。当 aTask失败时,它会在exception属性中设置失败的原因。要处理Task失败时的情况,您可以:

  • exception楼盘
  • 添加一个EventHandler来处理WorkerStateEvent.WORKER_STATE_FAILED事件并查询exception属性
    • 要么使用要么task.setOnFailed(EventHandler)task.addEventXXX(EventType, EventHandler)哪里XXX要么FilterHandler
  • 覆盖实现中的protected void failed()方法Task并查询exception属性
    • failed()方法将始终在 JavaFX 应用程序线程上调用
  • call()在重新抛出之前捕获并处理方法中的异常
  • 可能我目前没有想到的其他方式

推荐阅读