JavaFX - 让ScrollPane自动滚动

10

我在一个ScrollPane中有一个Label。我在循环中更新标签(在另一个线程中)。如果用户没有保持在固定位置,那么如何更新ScrollPane以向下滚动(不是左右滚动,这将手动完成)?是否有对应的setter方法?


你能解释一下“如果用户没有将其保持在某个位置”的意思吗? - Math
如果用户没有滚动。 - user3029101
6个回答

22

要自动将ScrollPane滚动到底部,请设置ScrollPane元素的vvalue,如下所示:

@FXML private ScrollPane scroll; //this must match the fx:id of the ScrollPane element
scroll.setVvalue(1.0);           //1.0 means 100% at the bottom

1
这个不起作用。(离题:为什么要使用FXML?(我有时使用Java和CSS))。实际上,它只在我在选项卡上时才能工作。(如果我已经打开了特定的选项卡) - user3029101
FXML 文件是您构建场景的地方,然后在 Controller.java 中,通过将变量与元素的 fx:id 关联来操作这些元素。如果它只在选项卡中工作,那么这意味着您必须在其他地方放置 .setVvalue(),具体取决于您想何时触发它,可能要与写入标签的位置一起在线程中执行。 - Math
我使用纯Java构建我的场景。 - user3029101
嗯...你也有这个选项,但我放弃了,因为我知道SceneBuilder。它可以独立于你的IDE工作,并自动化构建FXML文件的过程。在我看来,至少值得一看。 - Math
好的,明白了。我有一个想法。既然这个东西只在我查看选项卡时才起作用,我将添加一个监听器(选项卡更改/选择事件),然后设置vvalue。我找到了不同的代码片段。它们都没有起作用。我有一个TabPane。 - user3029101

7

要完全将滚动窗格滚动到底部,将其 vvalue 属性 设置为 1.0

scrollPane.setVvalue(1D);

请注意,当调整滚动面板的内容大小后调用此方法可能无法正常工作。
在这种情况下,如果通过Platform.runLater()延迟调用无法解决问题,请考虑根据内容height属性失效事件设置属性值:

vBox.heightProperty().addListener(observable -> scrollPane.setVvalue(1D));

6
这在我的代码中是可行的:
scrollPane.vvalueProperty().bind(mainGrid.heightProperty());

在我的情况下,scrollPane 包含 mainGrid。

5
如果您在ScrollPane中使用HBox或VBox,请尝试以下操作:
hBox.heightProperty().addListener(new ChangeListener() {
    @Override
    public void changed(ObservableValue observable, Object oldvalue, Object newValue) {
        scrollPane.setHvalue((Double)newValue );  
    }
});

只有当框的高度大于或等于1.0时,也就是hvalue属性的默认最大值时,这才能偶然起作用,而hvalue属性应该是vvalue。因此,仅需要一个无效化监听器。请参见我的答案以获取更正确的解决方案。 - spongebob

3

@Math 谢谢,解决了问题!

@FXML private ScrollPane scroll; //this must match the fx:id of the ScrollPane element or be the scrollpane object
scroll.setVvalue(1.0);           //1.0 means 100% at the bottom

我用以下代码解决了“必须查看选项卡”的问题

tab.setOnSelectionChanged(new EventHandler<Event>() {
    @Override
    public void handle(Event arg0) {
        ScrollPane.setVvalue(1.0);
    }        
});

实际上,您的问题中并没有太多关于滚动应该触发哪个事件的信息,因此我无法自行确定。 - Math
无论如何,问题就在于制表符,但我想把我做的事情包括进来,以防有人觉得它有用! - user3029101

0
这应该能解决问题:
// adding a new row
vbox_event.addEventRow((Integer) null, null);
// scroll to bottom
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        scrollpane.setVvalue(1.0);
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接