JavaFX-任务的新阶段 [英] JavaFX- new Stage in a task

查看:65
本文介绍了JavaFX-任务的新阶段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to open a new window from the task but for some reason after line Stage stage = new Stage the code stops executing, but there is no error.

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;
        }
    };

它从不打印出打印"消息.

It never prints out the message 'Print'.

推荐答案

问题解答

Task失败的原因是因为您正在JavaFX Application Thread之外的其他线程上创建Stage. Stage的Javadoc指出:

Answer to Question

The reason your Task is failing is because you are creating a Stage on a thread other than the JavaFX Application Thread. The Javadoc of Stage states:

必须在JavaFX Application Thread上构造和修改阶段对象.

Stage objects must be constructed and modified on the JavaFX Application Thread.

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

This means when you attempt to create a Stage on the background thread that the Task is running on it will result in an IllegalStateException with a message telling you that you aren't on the JavaFX Application Thread. To solve this issue wrap all code that creates and/or modifies a Stage in a Platform.runLater(Runnable) call.

侧面说明:最好根本不在Task中创建Stage.相反,在您的情况下,仅在处理Task成功时返回FXMLLoader.load(URL)的结果并创建Stage.

Side Note: It would probably be better to not create the Stage in the Task at all. Rather, in your case, simply return the result of FXMLLoader.load(URL) and create the Stage when handling the success of the 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();
};

为什么没有显示错误?

您说没有错误,但是您也不会显示任何代码,如果发生的话会显示错误.当Task失败时,它将在 exception 属性.要处理Task失败的情况,您可以:

Why No Error Shown?

You say there is no error but you also don't show any code that would display an error if one does occurr. When a Task fails it sets the cause of failure in the exception property. To handle the case when a Task fails you can:

  • 收听exception属性
  • 添加EventHandler来处理WorkerStateEvent.WORKER_STATE_FAILED事件并查询exception属性
    • 使用task.setOnFailed(EventHandler)task.addEventXXX(EventType, EventHandler),其中XXXFilterHandler
    • Listen to the exception property
    • Add an EventHandler to handle a WorkerStateEvent.WORKER_STATE_FAILED event and query the exception property
      • Either using task.setOnFailed(EventHandler) or task.addEventXXX(EventType, EventHandler) where XXX is either Filter or Handler
      • failed()方法将始终在JavaFX Application Thread上被调用
      • The failed() method will always be called on the JavaFX Application Thread

      这篇关于JavaFX-任务的新阶段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆