访问GridPane节点的问题 [英] Problems with accessing GridPane Node

查看:127
本文介绍了访问GridPane节点的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望你能帮助我完成一个我想做的小项目。我正在尝试使用JavaFX为GUI创建一个视频游戏,我遇到了一些麻烦。这是我为练习而制作的代码,我不知道为什么这不起作用。

i hope you can help me with a little project I want to do. I'm trying to create a video game using JavaFX for the GUI and I'm having some troubles. Here is the code I made for practice and I don't know why this don't work.

public class Main extends Application {
public GridPane map;
private int MAXH = 40;
private int MAXV = 40;
Random r = new Random();

@Override
public void start(Stage primaryStage) throws Exception{

    map = new GridPane();
    map.setGridLinesVisible(true);

    map.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent mouseEvent) {
            //Get X position
            int posX = (int) mouseEvent.getX() / 40;
            //Get Y position
            int posY = (int) mouseEvent.getY() / 40;

            System.out.println("(" + posX + " " + posY + ")");

            Canvas c = getCanvasNode(map, posX, posY);
        }
    });

    for (int i = 0; i < MAXH; i++){
        for(int j = 0; j < MAXV; j++){
            //For each cell create a Canvas node
            Canvas c = new Canvas(40, 40);
            GraphicsContext gc = c.getGraphicsContext2D();
            int k = r.nextInt();


            //Randomly paint the Canvas
            if (k % 3 == 0) gc.setFill(Color.BLUE);
            else if (k % 2 == 0) gc.setFill(Color.RED);
            else if (k % 7 == 0)gc.setFill(Color.GREEN);

            //Filling the Canvas
            gc.fillRect(0, 0, 40, 40);
            //Adding to our Grid Pane
            map.add(c, i, j);
        }
    }

    primaryStage.setHeight(700);
    primaryStage.setWidth(1200);
    primaryStage.setScene(new Scene(map));
    primaryStage.show();


}

private Canvas getCanvasNode(GridPane gridPane, int col, int row) {
    for (Node node : gridPane.getChildren()) {
        if (GridPane.getColumnIndex(node) == col && GridPane.getRowIndex(node) == row) {
            return (Canvas) node;
        }
    }
    return null;
}

public static void main(String[] args) {
    launch(args);
}}

当我使用产生null的函数getCanvasNode时问题就出现了指针异常,我不知道为什么。

The problem becomes when I use the function "getCanvasNode" which produces a null pointer exception and i don't know why.

我想要做的是获取我在地图上点击的节点事件处理程序可以有人帮助我吗?

What i want to do is get the node in which i click-on through the map Event Handler can someone help me?

PD:我不知道这是否是最有效/最简单的方法,如果有人可以给我一些很棒的提示。我是Java / JavaFX的新手。

PD: I dont know if this is the most efficient/simple way to do this, if someone could give me some tips it would be awesome. I'm new in Java/JavaFX.

推荐答案

当你这样做时

for (Node node : gridPane.getChildren()) { ... }

您遍历网格窗格的所有子节点,无论这些节点是您自己添加的节点,还是属于网格窗格内部实现的节点。

you iterate through all the child nodes of the grid pane, whether those are nodes you have added yourself, or nodes that are part of the internal implementation of the grid pane.

在你的情况下实际发生的是,因为你已经调用了

What is actually happening in your case is that, because you have called

map.setGridLinesVisible(true);

网格窗格添加了一个子节点来表示网格线。此节点没有为 columnIndex rowIndex 设置的属性。因此,当循环遇到该节点时, GridPane.getColumnIndex(node)抛出 NullPointerException 。 ( getColumnIndex 的实现在节点的属性映射中查找具有特定键的 Integer 对象,然后隐式调用 intValue()关于结果。所以如果没有设置值,它会尝试在一个<上调用 intValue() code> null reference。)

the grid pane has added a child node to represent the grid lines. This node doesn't have properties set for the columnIndex or rowIndex. So when the loop encounters that node, GridPane.getColumnIndex(node) throws a NullPointerException. (The implementation of getColumnIndex looks in the node's property map for an Integer object with a specific key, and then implicitly calls intValue() on the result. So if no value is set, it attempts to call intValue() on a null reference.)

所以你可以通过做一些基于

So you can fix this by doing something along the lines of

Integer columnIndex = GridPane.getColumnIndex(node);

然后处理特殊情况:

if (columnIndex != null && columnIndex.intValue() == col)  

等。

然而,对于你想要实现的目标,有一个更好的方法。不是在窗格中注册监听器,然后深入挖掘以找出被点击的子节点,而只需向子节点注册监听器:

However, there is a far better approach to what you are trying to achieve. Instead of registering a listener with the pane, and then digging in to find out which child was clicked, just register listeners with the child nodes instead:

for (int i = 0; i < MAXH; i++){
    for(int j = 0; j < MAXV; j++){
        //For each cell create a Canvas node
        Canvas c = new Canvas(40, 40);
        GraphicsContext gc = c.getGraphicsContext2D();
        int k = r.nextInt();


        //Randomly paint the Canvas
        if (k % 3 == 0) gc.setFill(Color.BLUE);
        else if (k % 2 == 0) gc.setFill(Color.RED);
        else if (k % 7 == 0)gc.setFill(Color.GREEN);

        //Filling the Canvas
        gc.fillRect(0, 0, 40, 40);
        //Adding to our Grid Pane
        map.add(c, i, j);

        String message = "Click on cell ["+i+", "+j+"]";
        c.setOnMouseClicked(e -> {
            System.out.println(message);
            // do anything else you need with the canvas....
        });
    }
}

这篇关于访问GridPane节点的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆