简体   繁体   中英

JavaFX rectangle mouseonclick grid return

I am writing a board game which has a 20x20 grid.

This is in my board class:

private final Position[][] grid = new Position[GRID_SIZE][GRID_SIZE];

each position has :

public class Position {

    private final Coordinates pos;
    private Player player;

    private final static double RECTANGLE_SIZE = 40.0;
    private final Rectangle rect = new Rectangle(RECTANGLE_SIZE, RECTANGLE_SIZE);
}

so basically I have 20x20 Positions and each positions has a Rectangle

This is what I do to display the grid

for (int cols = 0; cols < GRID_SIZE; ++cols) {
    for (int rows = 0; rows < GRID_SIZE; ++rows) {
        grid.add(gameEngine.getBoard().getGrid()[cols][rows].getRect(), cols, rows);
    }
}

Anyway, the grid is initialized and works properly. What I want to do is to make the rectangle objects clickable and to be able to return their Coordinates when they are clicked.

This is how I handle the mouse click

private void setUpRectangle() {
    rect.setOnMouseClicked(new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            rect.setFill(Color.BLACK);
        }
    });
}

What this code does is to change the color of the rectangle to black, but how could I return the Coordinates. Basically, I can edit the onclick function to return the coordinates of this position, but how can I acquire them later?

This is not a JavaFX question as much as it is a design question. You have a container ( Position ) of 2 objects ( Coordinates and Rectangle ) and you want one of them to know about the other. That is, the rectangle should know the coordinates of its position.

There are a few approaches here, and depending on the bigger picture, one might be better than the others. James_D mentioned a couple in a comment .

  1. Keep a reference of the position object in the rectangle object. This is useful if rectangle needs to access various datum in the container from various places. You would do something like rectangle.getPosition().getCoordinates() or .getPlayer() .
  2. Keep a reference of the coordinates object in the rectangle object. This is a more specific approach of 1 useful if you only need that object. You would do something like rectangle.getCoordinates() .
  3. Pass the coordinates to your setUpRectangle method. This is useful if you rectangle doesn't need access to this data from various places, it's a local solution. Then in the handle method you would return the coordinates you passed to setUpRectangle , though we can't see what class this method is in.
  4. Use external help. You can keep something like Map<Rectangle, Coordinates> and then call map.get(rectangle) . You can hide this map in a method Coordinates getCoordinatesForRectangle(Rectangle rectangle) instead of calling it directly.

You could store this data as userData (or use properties in case userData is preserved for something else in your program):

private final Rectangle rect;

public Position() {
    rect = new Rectangle(RECTANGLE_SIZE, RECTANGLE_SIZE);
    rect.setUserData(this);
}
rect.setOnMouseClicked((MouseEvent event) -> {
    Position pos = (Position) ((Node) event.getSource()).getUserData();
    ...
});

You could also use a listener that knows about the position:

class CoordinateAwareListener implements EventHandler<MouseEvent> {
    private final int coordinateX;
    private final int coordinateY;

    public CoordinateAwareListener(int coordinateX, int coordinateY) {
        this.coordinateX = coordinateX;
        this.coordinateY = coordinateY;
    }

    @Override
    public void handle(MouseEvent event) {
        // do something with the coordinates
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM