Autoscroll JavaFX TextFlow



我有一个包裹在ScrollPane中的JavaFX TextFlow,我试图让它在向TextFlow添加新Text时自动滚动到底部。

我尝试将听众附加到最大ScrollPane vvalue

  • ScrollPane vvalue财产本身。
    • 这会将ScrollPane锁定在底部,这是不需要的。
  • ScrollPaneviewportBounds财产。
    • 这是行不通的。
  • TextFlow的子弟名单。
    • 奇怪的是,这会滚动到添加最新Text之前位于底部的位置。我尝试在滚动之前显式请求布局,但这没有效果

为了特别感谢,我想滚动这样,如果新添加的内容太大而无法立即显示,ScrollPane滚动,使新添加的内容位于顶部,用户应手动滚动以查看"溢出"。正如我所说,这将是一个额外的好处,只是滚动到底部就可以了,因为我不希望有这么大的添加(定期)。

不,我不是在切换到 TextArea ,其中这将相对简单。我希望能够轻松地将常规,粗体和斜体文本添加到TextFlow,而TextArea不支持此功能。我也尝试了Thomas Mikula的RichTextFX,但是

  1. 它一直在不加解释地在内部代码上抛出StackOverflowError
  2. 我真的不想为这个项目使用第三方库。

因此,任何适用于TextFlow的解决方案都将不胜感激。

编辑:解决方案,根据要求:

private ScrollPane textContainer;
private TextFlow text;
public BaseGui() {
    //....
    text.getChildren().addListener(
                (ListChangeListener<Node>) ((change) -> {
                    text.layout();
                    textContainer.layout();
                    textContainer.setVvalue(1.0f);
                }));
    textContainer.setContent(text);
    //....
}
public void appendBold(String msg) { //similar for italic and regular
    append(msg, "-fx-font-weight: bold");
}
private synchronized void append(String msg, String style) {
    Platform.runLater(() -> {
        Text t = new Text(msg);
        t.setFont(segoe(13));
        if (!style.equals("")) {
            t.setStyle(style);
        }
        text.getChildren().add(t);
    });
}

它不会赢得任何代码风格的奖项,但由于这是一个个人项目,我并不在乎。

修改第 3 种方法以使用 layout() 而不是 requestLayout()

requestLayout()将布局标记为,并导致下一个脉冲重新布局。在代码中

requestLayout();
doSomethingThatDependsOnLayout();

doSomethingThatDependsOnLayout()将看到布局。

layout()立即(同步)执行布局,但前提是布局污。(在您的情况下,更改 TextFlow 的文本会将其布局标记为脏。在代码中

layout();
doSomethingThatDependsOnLayout();

doSomethingThatDependsOnLayout()将看到新的布局。

最新更新