JavaFX-任务中的新阶段

问题描述 投票:0回答:2

我想从任务中打开一个新窗口但由于某种原因,在行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;
        }
    };

它从不打印出“打印”消息。

java javafx
2个回答
1
投票

Answer to Question

你的Task失败的原因是因为你在JavaFX应用程序线程以外的线程上创建了一个StageStage的Javadoc声明:

必须在JavaFX Application Thread上构造和修改Stage对象。

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

旁注:最好不要在Stage中创建Task。相反,在你的情况下,只需返回FXMLLoader.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();
};

Why No Error Shown?

你说没有错误,但你也没有显示任何代码,如果确实发生错误将显示错误。当Task失败时,它确定了exception财产失败的原因。要处理Task失败的情况,您可以:

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

0
投票

您需要一个Executor来启动该线程

Executor exec = Executors.newCachedThreadPool(runnable -> {
    Thread t = new Thread(runnable);
    t.setDaemon(true);
    return t;
});

exec.execute(task);
© www.soinside.com 2019 - 2024. All rights reserved.