1

I'm new to JavaFX (Java for that matter) and I want to be able to click a GridPane and have it display my room attributes in a side-panel(or to console at this point). I've managed to setup a mouse event but I don't think it's the right tool for the job. When I click anywhere in the grid, it returns "null" and won't give me the cell coordinates(maybe there's better or more useful info to gather here?).

I'm using Scene Builder as well.

enter image description here

Controller Class

import Data.Area;
import Model.Grid;
import Model.TileSet;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class Controller {
    InputStream rinput = getClass().getResourceAsStream("/red.png");
    Image red = new Image(rinput);
    ImageView redimg = new ImageView(red);


    InputStream binput = getClass().getResourceAsStream("/black.png");
    Image black = new Image(binput);

    InputStream pinput = getClass().getResourceAsStream("/pink.png");
    Image pink = new Image(binput);

    @FXML
    public GridPane gridmane;


    public void genSmall(ActionEvent actionEvent) throws IOException {

        Grid grid = new Grid(new Area(40, 40));
        grid.getPathfinder().shufflePartitions();
        grid.getPathfinder().fillPartitions();
        grid.getPathfinder().generateHallways();
        grid.getPathfinder().placeWalls();
        importGrid(gridmane, grid);

        gridmane.getScene().getWindow().sizeToScene();
    }

    public void genMed(ActionEvent actionEvent) throws IOException {

        Grid grid = new Grid(new Area(60, 60));
        grid.getPathfinder().shufflePartitions();
        grid.getPathfinder().fillPartitions();
        grid.getPathfinder().generateHallways();
        grid.getPathfinder().placeWalls();
        gridmane.getScene().getWindow().sizeToScene();
        gridmane.getScene().getWindow().setHeight(600);
        gridmane.getScene().getWindow().setWidth(600);
        importGrid(gridmane, grid);


    }

    public void genLarge(ActionEvent actionEvent) throws IOException {

        Grid grid = new Grid(new Area(80, 80));
        grid.getPathfinder().shufflePartitions();
        grid.getPathfinder().fillPartitions();
        grid.getPathfinder().generateHallways();
        grid.getPathfinder().placeWalls();
        gridmane.getScene().getWindow().sizeToScene();
        gridmane.getScene().getWindow().setHeight(800);
        gridmane.getScene().getWindow().setWidth(800);
        importGrid(gridmane, grid);


    }

    private void importGrid(GridPane gridPane, Grid grid) {
        gridPane.getChildren().clear(); // remove old children

        for (int i = 0; i < grid.getSize().height; i++) {
            for (int j = 0; j < grid.getSize().width; j++) {
                if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.floorTile) {
                    changeSquare(gridPane, i, j, Color.WHITE, red);
                }
                else if (grid.getContent()[j + (i * grid.getSize().width)] == TileSet.wallTile) {

                    changeSquare(gridPane, i, j, Color.GRAY, black);

                }
                else {
                    changeSquare(gridPane, i, j, Color.BLACK, pink);
                }
            }
        }
    }

    private void changeSquare(GridPane gridPane, int xCoordinate, int yCoordinate, Color color, Image image) {
        Rectangle rect = new Rectangle();
        ImageView fimage = new ImageView(image);
        rect.setStroke(Color.BLACK);
        rect.setFill(color);
        rect.setWidth(10);
        rect.setHeight(10);
        gridPane.add(fimage, xCoordinate, yCoordinate);
    }




    public void clickGrid(javafx.scene.input.MouseEvent event) {
        Node source = (Node)event.getSource() ;
        Integer colIndex = gridmane.getColumnIndex(source);
        Integer rowIndex = gridmane.getRowIndex(source);
        System.out.println("Mouse clicked cell: " + colIndex + "And: " + rowIndex);


    }
}

Main Class

public class Main extends Application {

    Stage stage = new Stage();
    int val = 40;

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.stage = primaryStage;
        setVal(val);

    }


    public static void main(String[] args) {
        launch(args);
    }

    public void setVal(int i) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("/view.fxml"));
        stage.setTitle("Dungeon Generator");

        stage.setScene(new Scene(root, 450, 450));
        //primaryStage.setResizable(false);
        stage.sizeToScene();
        stage.show();
    }


}

FXML File

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?>

<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="258.0" prefWidth="332.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
   <children>
      <MenuBar>
        <menus>
          <Menu mnemonicParsing="false" text="File">
            <items>
              <MenuItem mnemonicParsing="false" text="Close" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Edit">
            <items>
              <MenuItem mnemonicParsing="false" text="Delete" />
            </items>
          </Menu>
          <Menu mnemonicParsing="false" text="Help">
            <items>
              <MenuItem mnemonicParsing="false" text="About" />
            </items>
          </Menu>
        </menus>
      </MenuBar>
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
         <children>
            <Button alignment="CENTER" mnemonicParsing="false" onAction="#genSmall" prefHeight="27.0" prefWidth="64.0" text="Small" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
            <Button alignment="CENTER" mnemonicParsing="false" onAction="#genMed" text="Medium" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
            <Button alignment="CENTER" mnemonicParsing="false" onAction="#genLarge" prefHeight="27.0" prefWidth="66.0" text="Large" HBox.hgrow="ALWAYS">
               <HBox.margin>
                  <Insets left="20.0" />
               </HBox.margin>
            </Button>
         </children>
      </HBox>
      <StackPane>
         <children>
             <GridPane fx:id="gridmane" maxHeight="-Infinity" maxWidth="-Infinity" onMouseClicked="#clickGrid" VBox.vgrow="NEVER" />
         </children>
      </StackPane>
   </children>
</VBox>
Keithers
  • 354
  • 6
  • 23

1 Answers1

3

Since you register the event handler at the GridPane, the source of the event is the GridPane itself. You did not set the row/column index for the GridPane and it wouldn't contain any useful information.

In this case you need to get the node that was actually clicked from the MouseEvent:

public void clickGrid(javafx.scene.input.MouseEvent event) {
    Node clickedNode = event.getPickResult().getIntersectedNode();
    if (clickedNode != gridmane) {
        // click on descendant node
        Integer colIndex = GridPane.getColumnIndex(clickedNode);
        Integer rowIndex = GridPane.getRowIndex(clickedNode);
        System.out.println("Mouse clicked cell: " + colIndex + " And: " + rowIndex);
    }
}

In this case the code works like this since the children of your GridPane don't have children of their own that could be the intersected node.

If you want to add children that could have children of their own you need to go up through the node hierarchy until you find a child of the GridPane:

if (clickedNode != gridmane) {
    // click on descendant node
    Node parent = clickedNode.getParent();
    while (parent != gridmane) {
        clickedNode = parent;
        parent = clickedNode.getParent();
    }
    Integer colIndex = GridPane.getColumnIndex(clickedNode);
    Integer rowIndex = GridPane.getRowIndex(clickedNode);
    System.out.println("Mouse clicked cell: " + colIndex + " And: " + rowIndex);
}
fabian
  • 80,457
  • 12
  • 86
  • 114