ScrollPane javafx自动滚动(设置vvalue为1.0)只滚动到最后一项之前
ScrollPane javafx auto scrolling (setting vvalue to 1.0) only scrolls to the item before the last
所以,情况是...我在滚动窗格中有一个 vbox。我将 hbox 添加到 vbox 中,然后在每次插入后调用 vbox.setVvalue(1.0)
。
然而,有 5 个水平框,滚动器只会使最后一个可见项目成为第 4 个水平框 - 在当前看到的下方有一个水平框(需要向下滚动才能看到)。
我找到了一个解决方案,它将滚动窗格的 vvalue 属性 绑定到 vbox 的高度 属性,如下所示:scrollPane.vvalueProperty().bind(vbox.heightProperty())
我假设每次都会将 vvalue 更改为最大值vbox 高度更改的时间(即添加新的 hbox 时)。
但是,我仍然想提高我的知识,以及为什么第一个(在每次插入后设置滚动窗格的 vvalue)与绑定属性不同。谢谢!
设置新的 vvalue
发生在由修改 VBox
引起的布局传递之前,但结果在布局传递之前应用。由于视口中显示的顶部 y 坐标的公式为
top = max(0, vvalue * (contentHeight - viewportHeight))
并且在布局过程中,内容的左上角保持在原位,您会在视口底部看到旧内容的底部。
要解决此问题,您可以使用
在 ScrollPane
上手动触发布局传递
scrollPane.applyCss();
scrollPane.layout();
例子
@Override
public void start(Stage primaryStage) {
VBox content = new VBox();
ScrollPane scrollPane = new ScrollPane(content);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
Button button = new Button("fill");
button.setOnAction(evt -> {
for (int i = 0; i < 20; i++) {
content.getChildren().add(new Text(Integer.toString(i)));
}
System.out.println("content size before layout: " + content.getHeight());
// manually layout scrollPane
scrollPane.applyCss();
scrollPane.layout();
System.out.println("content size after layout: " + content.getHeight());
scrollPane.setVvalue(1d);
});
Scene scene = new Scene(new VBox(button, scrollPane), 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
所以,情况是...我在滚动窗格中有一个 vbox。我将 hbox 添加到 vbox 中,然后在每次插入后调用 vbox.setVvalue(1.0)
。
然而,有 5 个水平框,滚动器只会使最后一个可见项目成为第 4 个水平框 - 在当前看到的下方有一个水平框(需要向下滚动才能看到)。
我找到了一个解决方案,它将滚动窗格的 vvalue 属性 绑定到 vbox 的高度 属性,如下所示:scrollPane.vvalueProperty().bind(vbox.heightProperty())
我假设每次都会将 vvalue 更改为最大值vbox 高度更改的时间(即添加新的 hbox 时)。
但是,我仍然想提高我的知识,以及为什么第一个(在每次插入后设置滚动窗格的 vvalue)与绑定属性不同。谢谢!
设置新的 vvalue
发生在由修改 VBox
引起的布局传递之前,但结果在布局传递之前应用。由于视口中显示的顶部 y 坐标的公式为
top = max(0, vvalue * (contentHeight - viewportHeight))
并且在布局过程中,内容的左上角保持在原位,您会在视口底部看到旧内容的底部。
要解决此问题,您可以使用
在ScrollPane
上手动触发布局传递
scrollPane.applyCss();
scrollPane.layout();
例子
@Override
public void start(Stage primaryStage) {
VBox content = new VBox();
ScrollPane scrollPane = new ScrollPane(content);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
Button button = new Button("fill");
button.setOnAction(evt -> {
for (int i = 0; i < 20; i++) {
content.getChildren().add(new Text(Integer.toString(i)));
}
System.out.println("content size before layout: " + content.getHeight());
// manually layout scrollPane
scrollPane.applyCss();
scrollPane.layout();
System.out.println("content size after layout: " + content.getHeight());
scrollPane.setVvalue(1d);
});
Scene scene = new Scene(new VBox(button, scrollPane), 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}