2013-07-22 58 views
12

我想讓TextArea自動滾動到底部,並通過事件處理程序放入新文本。每個新條目都只是一長串文本,每個條目都用換行符分隔。我試過一個更改處理程序,它將setscrolltop設置爲Double.MIN_VALUE,但無濟於事。任何想法如何做到這一點?JavaFX TextArea和自動滾動

+1

您的評論已被刪除(不是我),因爲您已將其發佈爲答案。我在那裏回覆說,你可能想接受你所判斷的答案是正確的,讓其他人知道你找到了滿足你的解決方案。爲了做到這一點,除了你喜歡的答案之外,還要點擊'V',讓它變成綠色。這也適用於你的[自己的答案](http://stackoverflow.com/questions/19122056/camel-jpa-component-forcing-a-commit) – Math

回答

20

你有一個監聽器添加到TextArea元素滾動至底部時,它的值改爲:

@FXML private TextArea txa; 

... 

txa.textProperty().addListener(new ChangeListener<Object>() { 
    @Override 
    public void changed(ObservableValue<?> observable, Object oldValue, 
      Object newValue) { 
     txa.setScrollTop(Double.MAX_VALUE); //this will scroll to the bottom 
     //use Double.MIN_VALUE to scroll to the top 
    } 
}); 

但是當你使用setText(text)方法,因此,如果要將此偵聽器未觸發觸發它後setText(text)使用appendText(text)後馬上:

txa.setText("Text into the textArea"); //does not trigger the listener 
txa.appendText(""); //this will trigger the listener and will scroll the 
        //TextArea to the bottom 

這聽起來更像是一個錯誤,一旦setText()應該觸發changed監聽器,但它ð oesn't。這是我使用自己的解決方法,並希望它可以幫助你。

+2

'setScrollTop(Double.MIN_VALUE);'滾動到頂部,而'MAX_VALUE'滾動到底部。 –

+0

@AdamJensen我會在這裏做一個測試,因爲我前一段時間回答了這個問題,我只是不記得看過它。感謝您的報告。 – Math

+1

@AdamJensen你是對的。我只是修正了這一點。謝謝! – Math

7

txa.appendText(「」)將滾動到底部,沒有聽衆。如果您想要回滾並且文本正在不斷更新,則會成爲問題。 txa.setText(「」)將滾動條放回頂部,同樣的問題也適用。

我的解決方案是擴展TextArea類,將FXML標記從textArea改爲LogTextArea。當這個作品,這顯然會導致現場建設者的問題,因爲它不知道這是什麼成分是

import javafx.scene.control.TextArea; 
import javafx.scene.text.Font; 

public class LogTextArea extends TextArea { 

private boolean pausedScroll = false; 
private double scrollPosition = 0; 

public LogTextArea() { 
    super(); 
} 

public void setMessage(String data) { 
    if (pausedScroll) { 
     scrollPosition = this.getScrollTop(); 
     this.setText(data); 
     this.setScrollTop(scrollPosition); 
    } else { 
     this.setText(data); 
     this.setScrollTop(Double.MAX_VALUE); 
    } 
} 

public void pauseScroll(Boolean pause) { 
    pausedScroll = pause; 
} 

} 
3

替代那個奇怪的setText錯誤,而無需使用AppendText通過

textArea.selectPositionCaret(textArea.getLength()); 
textArea.deselect(); //removes the highlighting 
1

一編我會增加jamesarbrown的對此的迴應將是使用布爾屬性,以便您可以從FXML中訪問它。 就是這樣。

import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.scene.control.TextArea; 

public class LogTextArea extends TextArea { 
    private final BooleanProperty pausedScrollProperty = new SimpleBooleanProperty(false); 
    private double scrollPosition = 0; 

    public LogTextArea() { 
     super(); 
    } 

    public void setMessage(String data) { 
     if (isPausedScroll()) { 
      scrollPosition = this.getScrollTop(); 
      this.setText(data); 
      this.setScrollTop(scrollPosition); 
     } else { 
      this.setText(data); 
      this.setScrollTop(Double.MAX_VALUE); 
     } 
    } 

    public final BooleanProperty pausedScrollProperty() { return pausedScrollProperty; } 
    public final boolean isPausedScroll() { return pausedScrollProperty.getValue(); } 
    public final void setPausedScroll(boolean value) { pausedScrollProperty.setValue(value); } 
} 

然而,這個答案的問題是,如果你得到一個不合理的大量投入淹沒(可檢索從IO流日誌時發生)JavaFX的線程將鎖定,因爲文本區得到數據太多。