32

Is there any way to get a specific Node from a gridPane if I know its location (row and column) or any other way to get a node from a gridPane?

Georgi Georgiev
  • 3,854
  • 5
  • 29
  • 39

2 Answers2

43

I don't see any direct API to get node by row column index, but you can use getChildren API from Pane, and getRowIndex(Node child) and getColumnIndex(Node child) from GridPane

//Gets the list of children of this Parent. 
public ObservableList<Node> getChildren() 
//Returns the child's column index constraint if set
public static java.lang.Integer getColumnIndex(Node child)
//Returns the child's row index constraint if set.
public static java.lang.Integer getRowIndex(Node child)

Here is the sample code to get the Node using row and column indices from the GridPane

public Node getNodeByRowColumnIndex (final int row, final int column, GridPane gridPane) {
    Node result = null;
    ObservableList<Node> childrens = gridPane.getChildren();

    for (Node node : childrens) {
        if(gridPane.getRowIndex(node) == row && gridPane.getColumnIndex(node) == column) {
            result = node;
            break;
        }
    }

    return result;
}

Important Update: getRowIndex() and getColumnIndex() are now static methods and should be changed to GridPane.getRowIndex(node) and GridPane.getColumnIndex(node).

SedJ601
  • 12,173
  • 3
  • 41
  • 59
invariant
  • 8,758
  • 9
  • 47
  • 61
  • Is there any reason to use `java.lang.Integer` over the standard? – JamEngulfer Jan 29 '15 at 19:11
  • 1
    Please note that specifying `null` for the indices is also allowed; in this case the index is treated as `0`. In your case this results in a NPE though. – fabian Feb 06 '17 at 17:00
  • 2
    I think the methods `getRowIndex()` and `getColumnIndex()` only return a value if such a constraint has been set on the node i.e. there is no guarantee that these will return the column or row indices. – D-Dᴙum Mar 03 '17 at 10:07
  • @Fabian does this mean that GridPane.getMargin(node) will always return null when the node is the first row in the grid pane? – Bob Apr 19 '18 at 13:13
  • @Bob I wasn't writing about `margin`, but `GidPane.getMargin(node)` will return `null`, if no margin was set for `node`, whether it's in the first row or not. – fabian Apr 19 '18 at 13:41
  • 1
    @Fabian sorry, I meant getRowIndex. I have a scenario where getRowIndex(node) returns null but I expect 0. If I put that same node in any other row, the method returns 1,2,3... – Bob Apr 19 '18 at 13:49
  • 3
    Make sure your constraints are set. Scenebuilder likes to treat 0 as not set and nulls the field. So manually set the constraints in the fxml file. e.g . Also since it's not guaranteed to return a non-null value from getRowIndex/getColumnIndex you should use an Integer object and check for null in the if statement. e.g. if(null != nodeRow && null != nodeCol ... – Olmstov Dec 10 '18 at 20:26
2

The above answer from @invariant is totally correct but for some people that do it that way, there may be performances issues, especially with GridPanes that contain many elements. And also when working with loops (iterating over all the elements of a GridPane).

What I suggest you is to initialize a static array of all your element/nodes contained within the grid pane. Then use this array to get the nodes you need.

i.e.

1. have a double dimensional array :

private Node[][] gridPaneArray = null;

2. Call a method like so during the initialization of your view :

    private void initializeGridPaneArray()
    {
       this.gridPaneArray = new Node[/*nbLines*/][/*nbColumns*/];
       for(Node node : this.mainPane.getChildren())
       {
          this.gridPaneArray[GridPane.getRowIndex(node)][GridPane.getColumnIndex(node)] = node;
       }
    }

3. Get your node

Node n = this.gridPaneArray[x][y]; // and cast it to any type you want/need
Dorian Naaji
  • 116
  • 1
  • 6