2015-06-11 81 views
1

我有一個文本區域和保存按鈕的GUI。當我按下後者時,文本被保存。這大約需要2秒鐘。在保存按鈕的過程中,應該獲得另一個標題,而不是保存之前和之後。JavaFX和GUI線程:從線程更改按鈕文本

這裏是我的代碼:

saveButton.setText("Saving..."); 
    Util.print("Saving..."); 

    Thread saveIt = new Thread(new Runnable() { 
     @Override public void run() { 
      Platform.runLater(() -> { 
       try { 
        Thread.sleep(2000); 
       } catch (Exception ex) { 
        Util.print(ex); 
       } 
       saveButton.setText("Saved!"); 
       Util.print("Saved!"); 
      }); 
     } 
    }); 
    saveIt.setDaemon(true); 
    saveIt.start(); 

會發生什麼:

Saving... 
Saved! 

命令行打印:按下按鈕後

以下輸出在命令行中產生點擊saveButton後,直接點擊「保存...」。按saveButton 2秒後,命令行將打印「已保存!」並且按鈕標題更改爲「已保存!」。

我會期待什麼:

命令行輸出和按鈕標題秀「保存...」後直接我點擊保存按鈕。 2秒後,標題更改爲「已保存!」。

我該如何達到預期的行爲?

非常感謝您的幫助。

P.S .:我知道很多人在線程中改變GUI元素都有問題。我已經閱讀了關於它的一些關於StackOverflow &的文章,但這對我來說太難了。僅供參考,這裏是我的一些嘗試,到目前爲止,其他任務之間的事情:

Constantly Update UI in Java FX worker thread

Why am I getting java.lang.IllegalStateException "Not on FX application thread" on JavaFX?

javafx, update ui from another thread

http://blog.axxg.de/javafx-ui-thread-update/

回答

2

我不得不把Thread.sleep()方法的一部分了Platform.runLater來從使用Platform.runLater JavaFX的線程調用()處理。看似runLater()的工作量必須儘可能少。

Platform.runLater(() -> { 
    saveButton.setText("Saving..."); 
    Util.print("Saving..."); 
}); 


Thread saveIt = new Thread(new Runnable() { 
    @Override public void run() { 
     try { 
      sleep(2000); 
     } catch (Exception ex) { 
      Util.print(ex); 
     } 
     Platform.runLater(() -> { 
      saveButton.setText("Saved!"); 
      Util.print("Saved!"); 
     }); 
    } 
}); 
saveIt.setDaemon(true); 
saveIt.start(); 
+1

是的!您正在將JavaFX線程休眠。 –

2

嘗試包裝你的第一的setText到像這樣的Platform.runLater:

Platform.runLater(() -> { 
    saveButton.setText("Saving..."); 
}); 

到一個JavaFX UI組件的每次修改都有

+0

它在10個案例中的大約1箇中起作用。我已經嘗試在示例代碼中使用單獨的線程進行包裝,但也不起作用。也不是如果我使用Thread.join()。 –

+0

謝謝,你幫我找到了正確的答案。 –