JavaFX : How to get column and row index in gridpane?
I tried to get the row/column index of gridpane, when I click.
I am looking for method like as getSelectedColumn() in JTable(java swing)
I searched this. gridPane.getRowIndex(node)
But it doesn't help to me. Because it need node name to get row/column index.
I make a component of grid by for grammar. So the node name is same. How can I get the value? My partial code is below.
for (int i = 0; i < imageName.length; i++) {
try {
img = new Image(getClass().getResourceAsStream(imageName[i]));
} catch (Exception e) {
System.out.println("exception : " + e);
}
ImageView imageview = new ImageView(img);
imageview.setFitWidth(40);
imageview.setFitHeight(40);
HBox hbox= new HBox();
hbox.getChildren().add(imageview);
tile1.setHgap(40);
tile1.setVgap(40);
tile1.add(hbox, i+2, 0);
}
Here's an example about how you could do it if you want only a mouse listener on the gridpane and not on the nodes in the cells. For simplicity I used a Label as cell node, but you can use whatever you prefer.
public class Demo extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(final Stage primaryStage) {
Pane root = new Pane();
GridPane gridPane = new GridPane();
gridPane.setGridLinesVisible(true);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
Label label = new Label("Label " + i + "/" + j);
label.setMouseTransparent(true);
GridPane.setRowIndex(label, i);
GridPane.setColumnIndex(label, j);
gridPane.getChildren().add(label);
}
}
root.getChildren().add( gridPane);
Scene scene = new Scene(root, 400, 300, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.show();
gridPane.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
for( Node node: gridPane.getChildren()) {
if( node instanceof Label) {
if( node.getBoundsInParent().contains(e.getSceneX(), e.getSceneY())) {
System.out.println( "Node: " + node + " at " + GridPane.getRowIndex( node) + "/" + GridPane.getColumnIndex( node));
}
}
}
}
});
}
}
You see the clicked cell information in the console.
The same would work if you'd put the listener on the cell node instead of the gridpane, here as a lambda expression:
label.addEventFilter(MouseEvent.MOUSE_PRESSED, event -> System.out.println( "Node: " + label + " at " + GridPane.getRowIndex( label) + "/" + GridPane.getColumnIndex( label)));
But be aware that the getRowIndex and getColumnIndex methods work only if the data were previously set, as specified in the documentation to these methods.
I have no information about what you intend to achieve, but personally I prefer to work with the nodes themselves instead of some indices in a layout manager which may change.
As @Roland points out, you can also assign a listener to each node. When doing so you can use a single callback method with this approach (mouse-pressed handler as example, but works with others too):
Assigning the handler to the nodes. Let's assume you have an array of buttons:
for (Button button : buttons) {
button.setOnMousePressed(this::onPress);
}
Mouse pressed handler method:
void onPress(MouseEvent event) {
int column = GridPane.getColumnIndex((Node) event.getSource());
int row = GridPane.getRowIndex((Node) event.getSource());
System.out.println(String.format("Node clicked at: column=%d, row=%d", column, row));
}