获取 column/row 索引时出现 JavaFX 错误

JavaFX error while getting column/row index

我在 JavaFX 中遇到了一个奇怪的行为。 简而言之:

我有一个网格窗格并向位置添加一个元素让我们说(0、0。或者任何,只要行为 0 或列为 0)比 .fxml 文件不填充 row/column 属性 并保留它没有,默认为 0。但是如果我这样保留它并想要实现例如侦听器,它使用 GridPane.getColumnIndex(Node) 获取单击元素的位置;然后它抛出异常,使其工作的唯一方法是手动编辑 .fxml 文件并添加那些 column = 0 / row = 0.

这是一个错误吗?故意的行为?

这不是错误。请注意 Javadocs for GridPane.getRowIndex(...)

Returns the child's row index constraint if set.

Returns

the row index for the child or null if no row index was set

所以如果没有设置,返回的值不是布局中使用的默认值,而是null.

如果你不在 Node 上设置 GridPane.columnIndexGridPane.rowIndex 约束,并将其添加到 GridPane 的子节点列表中,默认将使用值:即这些属性为 0。 (其他值也有默认值,例如,如果没有设置columnSpan,则默认值为1。这意味着可以使用默认值,而不会增加节点的内存消耗。)

布局约束在放置在单元格中的节点上的工作方式是使用一些特定键将值添加到 Node 的属性。 (Node.getProperties() 方法只是 returns 一个 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");

如果你没有设置列索引,那么properties映射中就没有这样的映射,所以在这种情况下xnull.

如果你这样做

int x = GridPane.getColumnIndex(node);

并且还没有设置列索引,那么(因为您隐式地将返回的 Integer 拆箱为 int),您实际上是在调用

int x = ((Integer)node.getProperties().get("gridpane-column")).intValue();

这里,如果没有设置列索引,node.getProperties().get(...) returns nullGridPane.getColumnIndex(...)文档也有说明),所以你得到一个NullPointerException 当你隐式调用 intValue().