我在JavaFX中遇到了一个奇怪的行为。 简而言之:
我有一个网格窗格并添加一个元素到位置让我们说(0,0。或者无论如何,只要行为0或列为0),而不是.fxml文件不填充行/列属性保留没有,默认为0.但是如果我这样离开并希望实现例如listener,它使用GridPane.getColumnIndex(Node)获取clicked元素的位置;然后它抛出一个异常,让它工作的唯一方法是手动编辑.fxml文件并添加那些column = 0 / row = 0.
这是一个错误吗?意味着行为?
答案 0 :(得分:2)
这不是错误。请注意Javadocs for GridPane.getRowIndex(...)
说
如果设置,则返回子项的行索引约束。
<强>返回强>
子项的行索引,如果未设置行索引,则为null
因此,如果未设置它们,则返回的值不是布局中使用的默认值,而是null
。
如果您未在GridPane.columnIndex
上设置GridPane.rowIndex
和Node
约束,并将其添加到GridPane
的子节点列表中,则默认值为使用:即0表示这些属性。 (其他值也有默认值,例如,如果没有设置columnSpan
,则默认值为1
。这意味着可以使用默认值而不增加节点的内存消耗。)< / p>
布局约束对放置在单元格中的节点的工作方式是使用某些特定键将值添加到Node
的属性中。 (Node.getProperties()
方法只返回Map<Object, Object>
,它可以包含任意键值映射。所以代码
GridPane root = new GridPane();
for (int x = 0 ; x < 8; x++) {
for (int y = 0 ; y < 8 ; y++) {
Label label = new Label(String.format("Cell [%d, %d]", x, y));
root.getChildren().add(label);
GridPane.setColumnIndex(label, x);
GridPane.setRowIndex(label, y);
}
}
证明等同于
GridPane root = new GridPane();
for (int x = 0 ; x < 8; x++) {
for (int y = 0 ; y < 8 ; y++) {
Label label = new Label(String.format("Cell [%d, %d]", x, y));
root.getChildren().add(label);
label.getProperties().put("gridpane-column", new Integer(x));
label.getProperties().put("gridpane-row", new Integer(y));
}
}
当然第一个版本更强大(更清晰);你永远不应该使用第二个版本。
如果你这样做
Integer x = GridPane.getColumnIndex(node);
该方法是(我假设,我没有检查源代码)实现,因此它与调用
相同Integer x = (Integer)node.getProperties().get("gridpane-column");
如果您没有设置列索引,那么属性映射中就没有这样的映射,因此在这种情况下x
是null
。
如果你这样做
int x = GridPane.getColumnIndex(node);
并且没有设置列索引,然后(因为您隐式地将返回的Integer
拆箱到int
),您实际上是在调用
int x = ((Integer)node.getProperties().get("gridpane-column")).intValue();
此处,如果尚未设置列索引,node.getProperties().get(...)
将返回null
(同样由GridPane.getColumnIndex(...)
文档指定),因此当您获得NullPointerException
时隐式调用intValue()
。