JavaFX - 获取节点相对于其父级的坐标

3
我正在制作一个简单的图形界面,用于保存之前生成的图像。所有的图像都是正方形的,但我希望能够允许一些裁剪功能(更准确地说是从图像底部和顶部剪切相等的部分)。我想通过允许用户在图像上拖动阴影区域来实现这个功能,告诉用户这个区域将被裁剪掉。请参考下面的图片了解详情。为了启用这个拖动功能,我添加了一些小三角形,希望用户可以拖动它们,进而移动阴影区域。然而,三角形的坐标都很奇怪,似乎毫无意义。因此,我想知道获取三角形相对于ImageView(或它们的第一个共同父节点)的坐标的最佳方法,以ImageView边长为单位。例如,如果三角形位于中心,则其坐标为[0.5, 0.5]。

enter image description here

ImageView将在场景中移动,并且大小也会发生变化,因此重要的是我能够获取相对于ImageView以及ImageView大小的坐标。

如果有助于理解,这里还有节点的周围层次结构。多边形是三角形,区域是矩形。

enter image description here

感谢所有形式的帮助!


你是否在寻找Node.boundsInParent - Slaw
@Slaw 不确定那是什么。你能解释一下吗? - Ivar Eriksson
1
可能更容易根据场景坐标获取所有位置。只需获取三角形和“ImageView”的场景位置,然后进行自己的数学计算即可。 - Jai
1个回答

6
Node.getBoundsInParent 返回节点在其父级坐标系中的边界。例如,polygon.getBoundsInParent() 将返回 VBox 中的边界。
如果您需要“向上”移动一步,可以使用 parent.localToParentvBox.localToParent(boundsInVbox) 返回 AnchorPane 坐标系中的边界。
要获取相对于图像大小的值,只需将其除以其大小即可。
以下示例仅允许您将封面区域向一个方向移动,并且不检查区域是否相交,但应足以演示方法。
有趣的部分是按钮的事件处理程序。它将第二个图像的视口限制为未覆盖的第一个图像的部分。
private static void setSideAnchors(Node node) {
    AnchorPane.setLeftAnchor(node, 0d);
    AnchorPane.setRightAnchor(node, 0d);
}

@Override
public void start(Stage primaryStage) {
    // create covering area
    Region topRegion = new Region();
    topRegion.setStyle("-fx-background-color: white;");
    Polygon topArrow = new Polygon(0, 0, 20, 0, 10, 20);
    topArrow.setFill(Color.WHITE);
    VBox top = new VBox(topRegion, topArrow);
    top.setAlignment(Pos.TOP_CENTER);
    topArrow.setOnMouseClicked(evt -> {
        topRegion.setPrefHeight(topRegion.getPrefHeight() + 10);
    });

    // create bottom covering area
    Region bottomRegion = new Region();
    bottomRegion.setStyle("-fx-background-color: white;");
    Polygon bottomArrow = new Polygon(0, 20, 20, 20, 10, 0);
    bottomArrow.setFill(Color.WHITE);
    VBox bottom = new VBox(bottomArrow, bottomRegion);
    bottom.setAlignment(Pos.BOTTOM_CENTER);
    bottomArrow.setOnMouseClicked(evt -> {
        bottomRegion.setPrefHeight(bottomRegion.getPrefHeight() + 10);
    });

    Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
    ImageView imageView = new ImageView(image);

    setSideAnchors(top);
    setSideAnchors(bottom);
    setSideAnchors(imageView);
    AnchorPane.setTopAnchor(top, 0d);
    AnchorPane.setBottomAnchor(bottom, 0d);
    AnchorPane.setTopAnchor(imageView, 0d);
    AnchorPane.setBottomAnchor(imageView, 0d);

    AnchorPane container = new AnchorPane(imageView, top, bottom);

    ImageView imageViewRestricted = new ImageView(image);

    Button button = new Button("restrict");
    button.setOnAction(evt -> {
        // determine bouns of Regions in AnchorPane
        Bounds topBounds = top.localToParent(topRegion.getBoundsInParent());
        Bounds bottomBounds = bottom.localToParent(bottomRegion.getBoundsInParent());

        // set viewport accordingly
        imageViewRestricted.setViewport(new Rectangle2D(
                0,
                topBounds.getMaxY(),
                image.getWidth(),
                bottomBounds.getMinY() - topBounds.getMaxY()));
    });

    HBox root = new HBox(container, button, imageViewRestricted);
    root.setFillHeight(false);

    Scene scene = new Scene(root);

    primaryStage.setScene(scene);
    primaryStage.show();
}

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