当ScrollPane内容的高度增加时,有没有自动向下滚动ScrollPane控件的方法? 例如,我在屏幕底部(在ScrollPane内部)有一个TitledPane,当我展开它时,我希望ScrollPane向下滚动,这样我就可以看到整个TitledPane的内容。
你可以使用bind
方法将ScrollPane
的vvalue
属性与内部容器的heightProperty
绑定。例如,如果你在ScrollPane
中有一个VBox
:
scrollPane.vvalueProperty().bind(vBox.heightProperty());
我也遇到了同样的问题,尝试了答案中的多种方法。
我的问题是ScrollPane
内容被其他线程使用Platform.runLater()
更新,如果更新很快,之前的所有方法都不够好。
对于所有遇到此类问题的人,你可以简单地使用以下方法:
ScrollPane scrollPane = new ScrollPane();
scrollPane.needsLayoutProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
scrollPane.setVvalue(1.0);
}
});
titledPane.heightProperty().addListener((observable, oldValue, newValue) ->
vvalueProperty().set(newValue.doubleValue()));
在向垂直或水平滚动条传递值之前,您必须告诉scrollpane当前坐标的位置。
这段代码对我来说非常有效:
// 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.localToScene()
和 scrollPane.setVvalue()
来实现这种行为。innerPane.widthProperty().addListener((observable, oldValue, newValue) -> { scrollPane.setHvalue(1.0d); });
如果您尝试通过监听innerPane的子列表更改来更改滚动条位置,则不起作用,因为此更改在此时尚未与innerPane布局一起计算。因此,您必须注意宽度或高度属性!
不知道它是否仍然相关,我曾经遇到过类似的问题,这个解决方案对我有效。我需要在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);
我知道这段代码并不是很具有代表性,但如果有人需要实现的更多细节,我可以详细说明...
我使用了一个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();
}
vvalue
(垂直值)表示滚动条的垂直位置,以百分点表示(如其他评论中所述),范围从0到1(双倍)VBox
的height
(也是双倍)将大于1,因为您很可能没有高度小于像素的容器 这会导致将大值设置为滚动条位置 我认为这能够工作是因为如果vvalue
大于1,则将其视为1 - gkhaos