最近幾天我一直在使用JavaFX,FXML,任務和屬性進行實驗。我偶然發現了一種奇怪的行爲,希望你能幫助我更好地理解發生了什麼。JavaFX:僅在更新標籤時才應用線程JavaFX?
我有一個簡約的GUI,看起來像這樣:GUI
如果我按一下按鈕創建並啓動了新的任務。此任務將增加一個雙重屬性,並將新值寫入標籤並在ProgressBar中進行設置。任務的代碼可以在這裏看到:
public class TestTask extends Task<Void>{
private final DoubleProperty doubleValue = new SimpleDoubleProperty();
@Override
protected Void call() throws Exception {
for(double i = 0.1; i <= 1; i = i+0.1) {
doubleValue.set(i);
Thread.sleep(1000);
}
return null;
}
public DoubleProperty test() {
return doubleValue;
}
}
的FXML控制器的代碼如下:
public class FXMLDocumentController implements Initializable {
@FXML private Label label;
@FXML private Slider slider;
//Called when the Button is clicked
@FXML
private void handleButtonAction(ActionEvent event) {
TestTask task = new TestTask();
task.test().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
//Works without problems
slider.setValue(newValue.doubleValue());
//Throws an exception
label.setText("Value" + newValue.doubleValue());
});
new Thread(task).start();
}
}
如果我運行這段代碼試圖更新以下異常標籤結果:java.lang.IllegalStateException:不在FX應用程序線程上; currentThread =線程4。滑塊的更新工作正常,並沒有拋出任何東西。
閱讀SO下列問題後:
我明白,因爲我試圖內執行UI更新標籤的更新失敗Listener從TestTask線程調用,而不是從FXApplication線程調用。
我的問題是:爲什麼更新的滑塊工作和不會引發異常?更新在Listener內進行,因此在TestTask Thread內進行。不應該這個嘗試還會拋出「不在FX應用程序線程」異常?
在此先感謝您花時間幫助我。
有時會檢查線程,有時不會。它不一致。儘管如此,場景中的節點應該從應用程序線程更新... – fabian
@fabian但看到這樣的行爲仍然很奇怪。即使我減少TestTask內的睡眠時間並增加迭代次數,每次都能順利進行。當然,每個UI更新都必須在JavaFX線程內,但這種情況仍然很有趣。我會看看滑塊課,也許我會在那裏找到答案。 – JKostikiadis