访问GridPane节点的问题 [英] Problems with accessing GridPane Node
问题描述
我希望你能帮助我完成一个我想做的小项目。我正在尝试使用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屋!