首页 > 解决方案 > How to auto scroll a ScrollPane so that a node will be aligned at the top of the pane

问题描述

In my program, I have a ScrollPane which its content is a VBox with a lot of child nodes. Some of the nodes are links which you can click and it should jump to the link's destination (imagine clicking the links in the Contents in a Wikipedia article, it will jump to the corresponding section). I know that in order to vertically scroll the ScrollPane by code, I would use .setVvalue().

My thinking is that I will get the y-coordinate of the link's destination node and divide it by the content's total height, and use that value as the Vvalue. The problem is that how would I accurately get the y-coordinate of a node if it's nested in multiple containers (e.g. in 2 VBoxes) using .getBoundsInParent()? Also, am I even approaching this the correct way?

An example of what I mean:

Before clicking the link

After clicking the link

标签: javajavafx

解决方案


您可以使用localToParent多次从ScollPane'content节点的坐标系转换坐标:

public static Point2D transform(Node coordinatesNode, Node ancestor, double x, double y) {
    Point2D coordinates = new Point2D(x, y);
    while (coordinatesNode != ancestor) {
        coordinates = coordinatesNode.localToParent(coordinates);
        coordinatesNode = coordinatesNode.getParent();
    }
    return coordinates;
}

你可以例如使用

Point2D pt = transform(someNode, scrollPane.getContent(), 0, 0);

someNode获取内容中左上角的坐标scrllPane

我的想法是,我将获取链接目标节点的 y 坐标并将其除以内容的总高度,并将该值用作 Vvalue

这不是 100% 正确的。您需要包括这样一个事实,即vvalue = 1内容的底部显示在视口的底部而不是顶部。因此,视口顶部显示的内容部分的 y 坐标方程为

y = vvalue * (contentHeight - viewportHeight)

所以

vvalue = y / (contentHeight - viewportHeight)

当然,您需要单独处理contentHeight <= viewportHeighty > contentHeight - viewportHeight单独处理病例。

可以通过视口边界检索视口的高度

double viewportHeight = scrollPane.getViewportBounds().getHeight();

推荐阅读