1

I am making a Lights Out game in JavaFX. I have a BoardController class with an initializer method that adds Squares to a GridPane member board. This method calls another method that sets a mouse event listener on each Square.

In the event handler, I use GridPane.getRowIndex and GridPane.getColumnIndex. Then I need to get a node by its GridPane coordinates which I do in a function the handler calls. But there, GridPane.getRowIndex and GridPane.getColumnIndex return null. Why? How do I fix this?

Here's the code.

//set mouse handler on each square
private void setMouseHandlers()
{
    ObservableList<Node> children = board.getChildren();
    for(Node child : children)
      child.setOnMouseClicked(new EventHandler() {

        @Override
        public void handle(Event event) {
            int row = GridPane.getRowIndex(child);    //fine
            int col = GridPane.getColumnIndex(child); //fine

            int up_row = row-1;
            int down_row = row+1;
            int left_col = col-1;
            int right_col = col+1;

            toggleNodeColor((Shape)child);

            //this expression works but getrow/col index does not work in the next function calls even if I pass the children vector
            //System.out.println(GridPane.getRowIndex(child) + " " + GridPane.getColumnIndex(child));

            if(isInBounds(up_row,col))    toggleNodeColor((Shape) getNodeInGrid(up_row,col));
            if(isInBounds(down_row,col))  toggleNodeColor((Shape) getNodeInGrid(down_row,col));
            if(isInBounds(row,left_col))  toggleNodeColor((Shape) getNodeInGrid(row,left_col));
            if(isInBounds(row,right_col)) toggleNodeColor((Shape) getNodeInGrid(row,right_col));

        }
}

And here is getNodeInGrid:

private Node getNodeInGrid(final int row, final int col)
{
    Node result = null;
    ObservableList<Node> children = board.getChildren();
    for(Node child : children)
    {
        //FIXME these row/col idxs are all null even though the exact same code works in the setMouseHandlers() method
        if( (GridPane.getRowIndex(child) == row) && (GridPane.getColumnIndex(child) == col))  //NullPointer at this line
            {
                result = child;
                break;
            }
    }
    return result;
}
Community
  • 1
  • 1
BenK
  • 333
  • 1
  • 6
  • 14
  • check this out http://stackoverflow.com/questions/28320110/javafx-how-to-get-column-and-row-index-in-gridpane – Hamletkrita Apr 20 '16 at 06:22
  • I'm not sure how that helps. In my code, I have a listener on each node. In the answer to the question you linked, the listener is on the GridPane. Also, the getIndex methods work for me when they are called in my SetMouseHandlers function but not when they are called again in another function called by that. – BenK Apr 21 '16 at 01:01

1 Answers1

1

I've found the problem.

Printing out the result of gridPane.getRowindex(child)==null reveals that there is a "ghost child," one I did not add to the GridPane myself. Since I didn't add it, getRowIndex returns null on it because it never had its row and column set.

The quick 'n dirty fix is to add a check in GetNodeInGrid().

BenK
  • 333
  • 1
  • 6
  • 14