JavaFX TextArea 和 autoscroll

2022-09-02 02:23:28

我正在尝试让TextArea自动滚动到底部,其中包含通过事件处理程序放入的新文本。每个新条目只是一个长文本字符串,每个条目之间用换行符分隔。我尝试了一个将setscrolltop设置为Double.MIN_VALUE但无济于事的更改处理程序。关于如何做到这一点的任何想法?


答案 1

您必须向元素添加一个侦听器,以便在其值更改时滚动到底部: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


答案 2

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;
}

}

推荐