[英]Stage.close() doesn't work javafx
我有一個主窗口,當我按一個按鈕時,另一個窗口將打開。 一定時間后,該窗口應關閉。 因為它擴展了stage
所以我使用了super.close
,但是它不起作用。 我能做什么? 可能是因為我在服務任務中將其關閉導致的嗎?
public Game(int width, int height, int time) {
this.width = width - 15;
this.height = height - 15;
this.time = time;
this.layout = generateLayout();
this.scene = new Scene(this.layout, this.width, this.height);
super.initModality(Modality.APPLICATION_MODAL);
super.setScene(scene);
super.setResizable(false);
super.setTitle(TITLE);
this.cicle.reset();
this.cicle.start();
super.showAndWait();
}
在cicle
里面,我叫close()
有點困惑,但這是cicle
服務任務:
Service<Void> cicle = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
volatile boolean waiting = false;
@Override
protected Void call() throws Exception {
Timer.start();
while (Timer.update() / 1000 < time) {
System.out.println(Timer.update())
}
close();
return null;
}
};
}
};
問題是您試圖從JavaFX Application Thread之外的其他線程關閉Stage
。 查看Stage
的文檔,您將看到:
舞台對象必須在JavaFX Application Thread上構造和修改。
JavaFX應用程序線程是在JavaFX運行時啟動過程中創建的。 有關更多信息,請參見Application類和Platform.startup(Runnable)方法。
然而, Service
在啟動時將在后台線程上執行其Task
。 具體地, Task
的call()
方法在所述后台線程上執行。 我剛剛測試過嘗試在后台線程上關閉Stage
,以查看會發生什么(是否會引發異常)。 結果是一個java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
因此,在java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
。
您沒有看到此消息的原因是您沒有觀察到Service
的失敗。 您可以查看此問題的答案,以了解觀察失敗的方法。 答案專門討論Task
但是Service
存在相同的行為。
使代碼工作所需要做的是確保在JavaFX Application Thread上調用close()
。 最簡單的方法是將close()
包裝在Platform.runLater(Runnable)
調用中。
Service<Void> cicle = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
volatile boolean waiting = false;
@Override
protected Void call() throws Exception {
Timer.start();
while (Timer.update() / 1000 < time) {
System.out.println(Timer.update())
}
Platform.runLater(() -> close()); // wrapped in Platform#runLater
return null;
}
};
}
};
您還可以重寫Service.succeeded()
,它將始終在JavaFX Application Thread上被調用(但僅當Service
成功時才調用)。 在這種情況下,您將從call()
方法中刪除對close()
的call()
。
Service<Void> cicle = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
volatile boolean waiting = false;
@Override
protected Void call() throws Exception {
Timer.start();
while (Timer.update() / 1000 < time) {
System.out.println(Timer.update())
}
return null;
}
};
}
@Override
protected void succeeded() {
close();
}
};
還有其他方法:監聽state
屬性,使用setOnSucceeded(EventHandler)
等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.