簡體   English   中英

JavaFX-任務的新階段

[英]JavaFX- new Stage in a task

我想從任務中打開一個新窗口,但是由於某些原因,在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;
        }
    };

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

回答問題

Task失敗的原因是因為您正在JavaFX Application Thread之外的其他線程上創建Stage Stage的Javadoc指出:

舞台對象必須在JavaFX Application Thread上構造和修改。

這意味着,當您嘗試在正在其上運行Task的后台線程上創建一個Stage時,將導致IllegalStateException並顯示一條消息,告知您不在JavaFX Application Thread上。 要解決此問題,請在Platform.runLater(Runnable)調用中包裝所有創建和/或修改Stage代碼。

旁注:最好根本不在Task中創建Stage 相反,在您的情況下,僅在處理Task成功時返回FXMLLoader.load(URL)的結果並創建Stage

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失敗時的情況,您可以:

  • exception屬性
  • 添加一個EventHandler來處理WorkerStateEvent.WORKER_STATE_FAILED事件並查詢exception屬性
    • 使用task.setOnFailed(EventHandler)task.addEventXXX(EventType, EventHandler) ,其中XXXFilterHandler
  • 覆蓋Task實現中protected void failed()方法,並查詢exception屬性
    • failed()方法將始終在JavaFX Application Thread上調用
  • 在重新拋出異常之前,在call()方法中捕獲並處理異常
  • 我目前未想到的其他方式

您需要一個執行程序來啟動線程

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

exec.execute(task);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM