【问题标题】:How to get screen/scene center x,y of Rectangle within a GridPane?如何在 GridPane 中获取 Rectangle 的屏幕/场景中心 x、y?
【发布时间】:2016-12-02 10:42:18
【问题描述】:

我正在用 JavaFX8 实现一个简单的棋盘游戏。

对于游戏板,我决定使用 10x10 GridPane 并在表单的初始化方法中用矩形填充它的单元格。

private void drawBoard() {
    gridpaneBoard.getChildren().clear();
    for (int y = 0; y < gridpaneBoard.getRowConstraints().size(); y++)
        for (int x = 0; x < gridpaneBoard.getColumnConstraints().size(); x++) {
            Rectangle rect = new Rectangle(55,55);
            rect.setStroke(Color.BLACK);

            Tile tile = GameController.getInstance().getBoard().getTile(x, y);
            if (tile.hasBranch())
                rect.setFill(QuestionDifficulty.values()[tile.getBranch()
                                                         .getQuestion().getQuestion()
                                                         .getLevel()].getColor());
            else
                rect.setFill(Color.WHITE);

            gridpaneBoard.add(rect, x, y);
            gridpaneBoard.add(new Label(String.valueOf(tile.getNumber())), x, y);
        }
}

为了在掷骰子后为玩家标记移动设置动画,我认为我需要知道每个图块的中心 x 和中心 y(以创建从源图块到目标图块的路径过渡)。

我尝试了各种其他人的问题的答案,但对我来说一切都返回 0,0。

这是该场景中的容器层次结构:

这是当前输出的样子:

如果 GridPane 适合我想要实现的目标,我怎样才能获得孩子(在本例中为矩形)的屏幕/场景中心 x,y?

如果 GridPane 不好,你能指出我的替代方案以及我如何实现我想要的......

谢谢!

【问题讨论】:

  • 您需要知道 centerX 和 centerY 才能使标签在您的记录中居中?
  • 这可能是我的问题的另一种用途。但我主要关心的是找到路径转换的矩形中心。例如.. 将玩家令牌从 4 号地块移动到 12 号地块。 (动画在路径中也会有#5、#6、#7、#8、#9、#10、#11)
  • 解决了标签对齐问题,只需在行/列约束上运行并将 V / H 对齐设置为 V / H pos.CENTER。

标签: javafx-8 coordinates rectangles gridpane


【解决方案1】:

您可以简单地调用getBoundsInParent 以获取其父级中Node 的尺寸。

下面的例子稍微简化了一点,但它应该展示了这种方法:

@Override
public void start(Stage primaryStage) {
    GridPane gridpaneBoard = new GridPane();
    for (int y = 0; y < 10; y++) {
        for (int x = 0; x < 10; x++) {
            Rectangle rect = new Rectangle(55, 55);
            rect.setStroke(Color.BLACK);

            rect.setFill((x + y) % 2 == 0 ? Color.WHITE : Color.DARKGRAY);

            gridpaneBoard.add(rect, x, y);
        }
    }

    gridpaneBoard.setOnMouseClicked(evt -> {
        Node target = evt.getPickResult().getIntersectedNode();

        if (target != gridpaneBoard) {
            // in your case you'd need to make sure this is not the Label
            Bounds bounds = target.getBoundsInParent();
            System.out.println("bounds = " +bounds);
            System.out.println("centerX = " +(bounds.getMinX() + bounds.getWidth()/2));
            System.out.println("centerY = " +(bounds.getMinY() + bounds.getHeight()/2));
        }
    });

    Scene scene = new Scene(gridpaneBoard);

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

如果需要与GridPane 坐标不同的坐标,您可以将getBoundsInLocallocalTo... 结合使用:

Bounds bounds = target.localToScene(target.getBoundsInLocal());

用于场景边界或

Bounds bounds = target.localToScreen(target.getBoundsInLocal());

用于屏幕边界。

注意:这与任何修改 GridPane 子级布局方式的属性无关。

【讨论】:

  • 试过这个:paste.ofcode.org/kpkcc2gSbagTbL8zWevtQ6 并且所有矩形在中心 x,y 上返回 27.5。
  • @ckid 您可能在第一次布局传递之前调用了该代码。在这种情况下,GridPane 还没有设置它的孩子的位置。如果稍后在 ui 的输入事件上调用,则应该没有这样的问题。例如。如果您单击右下角的矩形,这就是我的代码打印的内容:bounds = BoundingBox [minX:504.0, minY:504.0, minZ:0.0, width:56.0, height:56.0, depth:0.0, maxX:560.0, maxY:560.0, maxZ:0.0] centerX = 532.0 centerY = 532.0
  • 没错,我在 drawBoard() 之后进行了 syso 的初始化。在 Roll 按钮的动作事件上测试了相同的代码,它给了我,似乎是预期的结果!谢谢!
【解决方案2】:

你可以使用:

-GridPane.getColumnIndex(Node)获取列索引。

-GridPane.getRowIndex(Node) 获取行索引。

-由于您知道您孩子的WidthHeight (55,55) (Rectangle),您可以只计算它的centerXcenterY,它是相对于它在容器中的位置,但是由于您使用 GridPane,我认为这是不可能的,因为它具有约束。您可以通过更改对象的容器或在另一个原始/列中完全重绘它来修复它,这是一个示例Replace a node at (row,col)

【讨论】:

  • 有没有办法获取 GridPane 的左上角 x,y 场景位置?我可能能够基于此获得每个图块的场景中心(并知道它们的宽度/高度和列/行数)。
  • 为什么不使用 TilePane ?
  • 现在试用了 TilePane。据我所知,它不允许向单个位置添加超过 1 个节点。使用 TilePane 是否可以或更轻松地获取儿童的屏幕/场景 x、y?
  • 每个位置有 1 个节点的问题通过添加带有 Rectangle 和 Text 而不是 Rectangle 的 StackPane 来解决。
猜你喜欢
  • 1970-01-01
  • 2022-12-20
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2019-09-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多