2016-07-29 52 views
0

我已閱讀關於此主題的其他文章在Stackoverflow上。但他們沒有一個完全符合我的問題。JavaFX:使用appendText自動滾動TextArea,但沒有Listeners

我想在TextArea中記錄一個算法。在算法的每次迭代中,此TextArea中的文本應通過appendText()進行擴展。

我的第一個問題是:我應該在哪裏創建新的線程,以及兩個線程如何相互通信(GUI和算法)?

在我的實際設計中,我有三個重要的類:包含TextArea的視圖,調用算法和算法的控制器,需要迭代次數和TextArea(調用appendText()在代碼中使用位置的方法)。

在這個設計中,控制器調用算法,該算法用for循環迭代n次,並在終止後,GUI顯示更改。但是當算法調用appendText()方法時,我希望GUI同時顯示更改。

而我的第二個問題是TextArea的自動滾動。在每次appendText-call之後,TextArea應完全向下滾動。但我認爲這個問題的解決方案與我的第一個問題是同樣的解決方案。

我會非常感謝您的幫助。

回答

0

在沒有(很多)更多信息的情況下完全回答你的問題幾乎是不可能的,但是我使用的一般方法是讓算法有一個回調來處理一條消息,這個消息可以被每一步該算法。在FX應用程序線程上,從控制器傳遞一個實現更新文本區域的回調函數。

喜歡的東西:

public class Algorithm { 

    private Consumer<String> statusCallback ; 

    public Algorithm(Consumer<String> statusCallback) { 
     this.statusCallback = statusCallback ; 
    } 

    public Algorithm() { 
     // by default, callback does nothing: 
     this(s -> {}); 
    } 

    public void performAlgorithm() { 

     while (! finished()) { 
      doNextStep(); 
      String statusMessage = getStatus(); 
      statusCallback.accept(statusMessage); 
     } 
    } 
} 

然後

public class Controller { 

    private View view = ... ; 

    public void startAlgorithm() { 
     Algorithm algorithm = new Algorithm(s -> Platform.runLater(view.appendStatus(s))); 
     Thread t = new Thread(algorithm::performAlgorithm); 
     t.setDaemon(true); 
     t.start(); 
    } 
} 

對於View然後執行以下操作(注意,你可以打倒textArea.setScrollTop(Double.MAX_VALUE);滾動):

public class View { 
    private TextArea textArea ; 

    public View() { 
     textArea = new TextArea(); 
     // ... 
    } 

    public void appendStatus(String status) { 
     if (!textArea.getText().isEmpty()) { 
      textArea.appendText("\n"); 
     } 
     textArea.appendText(status); 
     textArea.setScrollTop(Double.MAX_VALUE); 
    } 
} 

這隻要你的算法不會產生太多的狀態u就應該工作pdates速度太快(這樣它們會溢出FX應用程序線程並阻止它正常工作)。