当 ScrollPane 控件的内容高度增加时,有什么方法可以自动向下滚动?例如,我在屏幕底部(在 ScrollPane 内)有一个 TitledPane,当我展开它时,我希望 ScrollPane 向下滚动,这样我就可以看到 TitledPane 的全部内容。
8 回答
您可以使用内部容器bind
的ScrollPane
vvalue
属性。heightProperty
例如,如果您VBox
的ScrollPane
:
scrollPane.vvalueProperty().bind(vBox.heightProperty());
您可以通过结合titledPane.localToScene()
和来实现该行为scrollPane.setVvalue()
第一个是获取 titledPane 的坐标,第二个是设置 scrollPane 的垂直条位置。请注意,它的范围在 0 - 1 之间。
在将值传递给垂直或水平条之前,您必须告诉滚动窗格当前坐标在哪里。
这段代码对我来说很好用:
// the owner's node of your scrollPane;
titledPane.layout();
// the maxValue for scrollPane bar ( 1.0 it's the default value )
scrollPane.setVvalue( 1.0d );
您必须在滚动窗格增长的地方对此进行编码。例如,如果您将节点添加到滚动窗格内部节点,则将侦听器添加到其子列表中。
如果滚动窗格的内部节点改变了它的高度,则向 heightProperty 添加一个侦听器。
例如,您的 scrollPane 的内部节点是一个 AnchorPane 并且您将节点添加到此窗格,所以这样做:
anchorPane.getChildren().addListener(
( ListChangeListener.Change<? extends Node> c ) -> {
titledPane.layout();
scrollPane.setVvalue( 1.0d );
}
);
如果是身高增长...
heightProperty().addListener(
(observable, oldValue, newValue) -> {
titledPane.layout();
scrollPane.setVvalue( 1.0d );
}
);
就是这样!
您可以像这样向 TitledPane 的 height 属性添加一个侦听器:
titledPane.heightProperty().addListener((observable, oldValue, newValue) ->
vvalueProperty().set(newValue.doubleValue()));
我有同样的问题,我在答案中尝试了不止一种方法。我的问题是ScrollPane
内容正在从其他线程使用Platform.runLater()
更新,如果更新非常快,所有以前的方法都不够好。对于所有面临此类问题的人,您可以简单地使用这个:
ScrollPane scrollPane = new ScrollPane();
scrollPane.needsLayoutProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
scrollPane.setVvalue(1.0);
}
});
Donno 如果它仍然相关,我有一个类似的问题,这个解决方案对我有用。我需要滚动条以 MVVM 模式自动滚动。我所做的是将视图中 textarea 的 scrollTopProperty 与 ViewModel 中的 SimpleDoubleProperty 绑定。唯一的问题是 scrollTopProperty,基本上是基于像素滚动的,所以我根据车道数 * 100 增加了它;
看法
textArea.textProperty().bindBidirectional(viewModel.SimpleStringProperty());
textArea.scrollTopProperty().bindBidirectional(viewModel.SimpleDoubleProperty());
视图模型
SimpleDoubleProperty.setValue(SimpleStringProperty.getValue().split("\n").length * 100);
我知道代码并没有真正的代表性,但如果有人需要更多的实现细节,我可以详细说明......
innerPane.widthProperty().addListener((observable, oldValue, newValue) -> { scrollPane.setHvalue(1.0d); });
如果您尝试通过侦听 innerPane 子列表的更改来更改滚动条位置,则不起作用,因为此时尚未使用 innerPane 布局计算此更改。因此,您必须注意属性的宽度或高度!
我是通过使用 AnimationTimer 来完成的。我必须等待 100000000 纳秒才能确保 ScrollPane 已对扩展的 Titlepane 做出反应。
public void scrollNodeInTopScrollPane(Node n, ScrollPane s) {
final Node node = n;
final ScrollPane clientTopScrollPane = s;
AnimationTimer timer = new AnimationTimer() {
long lng = 0;
@Override
public void handle(long l) {
if (lng == 0) {
lng = l;
}
if (l > lng + 100000000) {
if (node.getLocalToSceneTransform().getTy() > 20) {
clientTopScrollPane.setVvalue(clientTopScrollPane.getVvalue() + 0.05);
if (clientTopScrollPane.getVvalue() == 1) {
this.stop();
}
} else {
this.stop();
}
}
}
};
timer.start();
}