代码之家  ›  专栏  ›  技术社区  ›  Grzegorz Brzęczyszczykiewicz

javafx-任务中的新阶段

  •  0
  • Grzegorz Brzęczyszczykiewicz  · 技术社区  · 7 年前

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

    它从不打印“打印”信息。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Slaw    7 年前

    对问题的回答

    你的原因 Task 失败是因为你正在创造一个 Stage 在javafx应用程序线程以外的线程上。的javadoc 舞台 国家:

    stage对象必须在javafx应用程序线程上构造和修改。

    这意味着当您试图创建 舞台 在后台线程中 任务 在上面运行会导致 IllegalStateException 一条消息告诉您您不在javafx应用程序线程上。若要解决此问题,请将创建和/或修改 舞台 在一个 Platform.runLater(Runnable) 打电话。

    边注: 最好不要创建 舞台 任务 完全。相反,在您的情况下,只需返回 FXMLLoader.load(URL) 并创建 舞台 当处理成功的 任务 .

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

    为什么没有显示错误?

    你说没有错误,但你也没有显示任何代码,将显示一个错误,如果一个发生。当A 任务 失败它设置失败的原因 exception 财产。当 任务 如果失败,您可以:

    • 听我说 例外 财产
    • 添加一个 EventHandler 处理 WorkerStateEvent.WORKER_STATE_FAILED 事件并查询 例外 财产
      • 要么使用 task.setOnFailed(EventHandler) task.addEventXXX(EventType, EventHandler) 哪里 XXX 要么是 Filter Handler
    • 重写 protected void failed() 你的方法 任务 实现并查询 例外 财产
      • 这个 failed() 方法将始终在javafx应用程序线程上调用。
    • 捕获并处理 call() 方法在重新抛出之前
    • 可能还有其他我现在没想到的方法
        2
  •  0
  •   Jesús Octavio Valenzuela López    7 年前

    你需要一个执行器来启动线程

    Executor exec = Executors.newCachedThreadPool(runnable -> {
        Thread t = new Thread(runnable);
        t.setDaemon(true);
        return t;
    });
    
    exec.execute(task);
    
    推荐文章