大家好,所以我在网上尝试了很多关于如何获取在Gridpane中点击的Node(单元格)的解决方案。我用于获取节点的方法如下所示。我也尝试在此方法之前迭代所有节点。我用scenebuilder构建了gridpane,正如你在下面的图片中看到的那样,列和行显然都在那里。我正在尝试此解决方案How to get GridPane Row and Column IDs on Mouse Entered in each cell of Grid in JavaFX?但是正如我上面提到的,从行和列返回的值为空。
@FXML
private void mouseEntered(MouseEvent e) {
Node source = (Node)e.getSource() ;
System.out.println(source);
Integer colIndex = userSelectionGrid.getColumnIndex(source);
Integer rowIndex = userSelectionGrid.getRowIndex(source);
if (colIndex == null && rowIndex == null) System.out.println("BOO");
else
System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
}
包含此网格的FXML
<GridPane fx:id="userSelectionGrid" onMouseClicked="#mouseEntered" prefHeight="44.0" prefWidth="563.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Separator orientation="VERTICAL" GridPane.columnIndex="1" />
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</GridPane>
答案 0 :(得分:2)
事件的来源是Node
,其中添加了处理程序,即在这种情况下GridPane
。您可以将处理程序添加到GridPane
的子项中,以使源Node
正确无误:
<GridPane fx:id="userSelectionGrid" prefHeight="44.0" prefWidth="563.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0" onMouseClicked="#mouseEntered">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0" onMouseClicked="#mouseEntered">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Separator orientation="VERTICAL" GridPane.columnIndex="1" />
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</GridPane>
请注意,您也可以使用原始fxml进行此操作。但是,您应该考虑以下几点:
null
也是GridPane.getRowIndex
和GridPane.getColumnIndex
的有效返回值,这并不意味着该节点不是GridPane
的子节点,它只是意味着该值未从默认值更改。这与使用值0
。条件
if (colIndex == null && rowIndex == null)
太强大,无法阻止其他部分NullPointerException
。这可能发生在例如如果点击了Separator
。
Node
皮肤中的Label
。在此节点中,您可以遍历父节点,直到父节点为GridPane
,以查找GridPane
的正确子节点。@FXML
private void mouseEntered(MouseEvent e) {
Node target = (Node) e.getTarget();
// traverse towards root until userSelectionGrid is the parent node
if (target != userSelectionGrid) {
Node parent;
while ((parent = target.getParent()) != userSelectionGrid) {
target = parent;
}
}
Integer colIndex = userSelectionGrid.getColumnIndex(target);
Integer rowIndex = userSelectionGrid.getRowIndex(target);
if (colIndex == null || rowIndex == null) {
System.out.println("BOO");
} else {
System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
}
}
请注意,除非您将首选大小设置为大于Label
约束,否则GridPane
不会填满GridPane
。这会弄乱GridPane
的布局。解决方法是将Region
放在单元格中的Label
后面。这些可以使用单元格调整大小而不影响GridPane
布局,这允许您在这些节点上捕获事件:
<GridPane fx:id="userSelectionGrid" prefHeight="44.0" prefWidth="563.0" onMouseClicked="#mouseEntered">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" fillWidth="true" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" fillWidth="true" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" fillHeight="true" />
</rowConstraints>
<children>
<Region GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Region GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Label>
<Separator orientation="VERTICAL" GridPane.columnIndex="1" />
</children>
<VBox.margin>
<Insets />
</VBox.margin>
</GridPane>