Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace a node at (row,col) in a JavaFX GridPane

I am making a grid-style game/simulation based on bugs "sensing" and eating food. I am using a gridPane (called worldGrid) of labels to show the grid of bugs and food. This is obviously going to be constantly updated when a bug moves cells towards food etc.

I currently have a function updateGrid(int col, int row, String cellContent) which I want to replace the label at [row,col] with a label that has the new text in cellContent.

I have the follow which works

worldGrid.add(new Label(cellContent), row,col);

however im worried that that is just adding a label on top of the current label and obviously over 100 iterations of the simulation thats not ideal.

I have tried this before adding the label:

worldGrid.getChildren().remove(row,col);

However I then get an IllegalArgumentException when trying to do the add line.

Any ideas on how to do this? Or even better, any ideas on how best to show a constantly changing grid that will eventually use sprites instead of text?

like image 939
JabbaWook Avatar asked Nov 26 '14 17:11

JabbaWook


People also ask

How do I add nodes to GridPane in JavaFX?

add(button6, 2, 1, 1, 1); The first parameter of the add() method is the component (node) to add to the GridPane . The second and third parameter of the add() method is the column index and row index of the cell in which the component should be displayed.

How do you get the column and row index of a node in a GridPane?

You can get the row index and column index by utilising the static methods getRowIndex() and getColumnIndex() which are located in the GridPane class. System. out. println("Row: " + GridPane.

How do I remove a node from GridPane?

removeIf( node -> GridPane. getColumnIndex(node) == col && GridPane. getRowIndex(node) == row); removeIf method removes all elements from the gridPane that satisfy the specified condition, given as method.

How do you add a row to GridPane in Scene Builder?

This feature exists in the JavaFX Scene Builder by right clicking on the GridPane and selecting GridPane, then it will show a list of options: Add Row Above, Add Row Below, Add Column After, Add Column Before. The results of each of these options are what I desire.


2 Answers

The col/row provided by grid.add(node, col, row) (ATTENTION first comes col!) is only a layout constraint. This does not provide any means to access columns or rows like slots in a 2-dimensional array. So to replace a node, you have to know its object itself, e.g. remember them in a separate array.

Then you are able to call getChildren().remove(object)... e.g.:

GridPane grid = new GridPane();

Label first = new Label("first");
Label second = new Label("second");

grid.add(first,  1,  1);
grid.add(second,  2,  2);
second.setOnMouseClicked(e -> {
    grid.getChildren().remove(second);
    grid.add(new Label("last"), 2, 2);
});
box.getChildren().addAll(grid);
like image 166
Jens-Peter Haack Avatar answered Sep 24 '22 14:09

Jens-Peter Haack


I agree with Jens-Peter but I would add that you can use GridPane's getColumnIndex and getRowIndex to obtain a particular node's location.

For example ( this is in a component which extends GridPane ):

// set the appropriate label
for (Node node : getChildren()) {
    if (node instanceof Label
     && getColumnIndex(node) == column
     && getRowIndex(node) == row) {
        ((Label)node).setTooltip(new Tooltip(tooltip));
    }
}

in other words, go through all the nodes in the GridPane and check for a match of the conditions you want, in this case row and column.

like image 42
T-and-M Mike Avatar answered Sep 21 '22 14:09

T-and-M Mike