我有一个包裹在ScrollPane
中的JavaFX TextFlow
,我试图让它在向TextFlow
添加新Text
时自动滚动到底部。
我尝试将听众附加到最大ScrollPane
vvalue
:
ScrollPane
vvalue
财产本身。- 这会将
ScrollPane
锁定在底部,这是不需要的。
- 这会将
ScrollPane
的viewportBounds
财产。- 这是行不通的。
TextFlow
的子弟名单。- 奇怪的是,这会滚动到添加最新
Text
之前位于底部的位置。我尝试在滚动之前显式请求布局,但这没有效果
- 奇怪的是,这会滚动到添加最新
为了特别感谢,我想滚动这样,如果新添加的内容太大而无法立即显示,ScrollPane
滚动,使新添加的内容位于顶部,用户应手动滚动以查看"溢出"。正如我所说,这将是一个额外的好处,只是滚动到底部就可以了,因为我不希望有这么大的添加(定期)。
不,我不是在切换到 TextArea
,其中这将相对简单。我希望能够轻松地将常规,粗体和斜体文本添加到TextFlow
,而TextArea
不支持此功能。我也尝试了Thomas Mikula的RichTextFX,但是
- 它一直在不加解释地在内部代码上抛出
StackOverflowError
。 - 我真的不想为这个项目使用第三方库。
因此,任何适用于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()
将看到新的布局。