亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在處理數據時正確更新 JavaFX GUI

如何在處理數據時正確更新 JavaFX GUI

當年話下 2023-06-04 17:09:39
我正在嘗試進入 JavaFX 以首次嘗試使用 Java 制作 GUI。因此,我制作了一個簡單的神經網絡來學習 XOR 并在 JavaFX 中顯示輸出。我的問題是 - 如何在處理數據時定期更新 GUI?到目前為止,我所取得的一切都是網絡完成學習后 GUI 中的一次更新。即使我在線程中啟動了網絡。我希望 GUI 的右側更新(圓圈根據輸出改變顏色)定期為每個 n 紀元而不是一次。附圖顯示了網絡啟動前的 GUI。
查看完整描述

1 回答

?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

JavaFX 有一個“事件線程”,負責處理按鈕點擊、更新標簽和任何其他與 GUI 相關的任務。當您調用時button.setOnAction(e -> doSomething());,當您按下按鈕時,doSomething()發生在 JavaFX 線程上。在此運行期間,不會發生其他 GUI 事件。這意味著您的界面將完全凍結,從而導致糟糕的用戶體驗。


此外,您不能在 JavaFX 線程以外的任何線程上執行 GUI 操作,否則您將獲得一個IllegalStateException. (試著打電話Executors.newSingleThreadExecutor().execute(() -> label.setText("hello"));看看這個在行動)


幸運的是,JavaFX 提供了解決這個問題的方法。


首先,也是最簡單的方法,是在新線程中調用長時間運行的方法(可能使用ExecutorService上面的 s),當您需要修改接口時,將這些調用包裝在對Platform.runLater(() -> updateInterface());. 這將發布updateInterface()到 GUI 線程,并允許它運行。


但是,這可能會很麻煩,因此首選方法是使用Service.


假設您的長時間運行的計算返回一個Double,您創建一個類 extending Service<Double>,覆蓋它的createTask()方法,并在那里執行計算,如下所示:


public class CalculationService extends Service<Double> {

? ? @Override

? ? protected Task<Double> createTask() {

? ? ? ? return new Task<Double>() {

? ? ? ? ? ? @Override

? ? ? ? ? ? protected Double call() throws Exception {

? ? ? ? ? ? ? ? return doCalculation();

? ? ? ? ? ? }

? ? ? ? };

? ? }

}

然后,在你的控制器中,聲明一個private final CalculationService service = new CalculationService();


在您的控制器initialize()方法中,您可以將此服務的輸出綁定到您想要的任何內容。例如:


calculationDisplayLabel.textProperty().bind(Bindings.createStringBinding(service.valueProperty()));

// continuously updates the label whenever the service calculates a new value

然后,每當您決定要重新開始計算時,service.restart()如果進程正在運行,您可以調用中斷進程,并從頭開始。


如果要在值更改時調用代碼,請向服務的值添加一個偵聽器。例如,如果您希望它在完成后立即重新計算,請調用:


service.valueProperty().addListener((obs, old, newValue) -> service.restart());

查看完整回答
反對 回復 2023-06-04
  • 1 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號