Question

I have a few objects on a board and I'd like to get those objects's indexes by the coordinates. I've tried making a MouseEvent handler and using the getBoundInParent() combined with MouseInfo.getPointerInfo().getLocation(), but unsuccessful. These methods gave me different coordinates and could not match them.

Should I make a rectangle by the cursor's coordinates and use the getBoundInParent().intersects method?

Any advices?

Was it helpful?

Solution

Solution

On each of the shapes, provide setOnMouseEntered and setOnMouseExited handlers to catch the mouse entering and exiting events and record the index of the shape which the mouse is over.

Assumption

I assume you need to intersect the cursor hotspot (e.g. the tip of the mouse pointer arrow) and not the cursor shape or the cursor's rectangular bounds (as intersection of the hotspot is the standard way that cursors work).

Sample Application Output

mouseover

  • When you mouse over the circle, the circle will be highlighted and the circle's index (1) will display
  • When you mouse over the rectangle, the rectangle will be highlighted and the rectangles's index (2) will display.
  • When you don't mouse over either shape, neither shape will be highlighted and no index will display.

Sample Code

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

public class ShapeIntersector extends Application {
    private static final Shape[] shapes = {
            new Circle(50, Color.AQUAMARINE),
            new Rectangle(100, 100, Color.PALEGREEN)
    };

    private static final DropShadow highlight =
            new DropShadow(20, Color.GOLDENROD);

    @Override
    public void start(Stage stage) throws Exception {
        HBox layout = new HBox(40);
        layout.setPadding(new Insets(30));
        layout.setAlignment(Pos.CENTER);

        Label highlightedShapeLabel = new Label(" ");
        highlightedShapeLabel.setStyle(
                "-fx-font-family: monospace; -fx-font-size: 80px; -fx-text-fill: olive"
        );

        for (Shape shape: shapes) {
            layout.getChildren().add(shape);

            shape.setOnMouseEntered(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    shape.setEffect(highlight);
                    int idx = layout.getChildren().indexOf(shape) + 1;
                    highlightedShapeLabel.setText(
                            "" + idx
                    );
                }
            });

            shape.setOnMouseExited(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    shape.setEffect(null);
                    highlightedShapeLabel.setText(" ");
                }
            });
        }

        layout.getChildren().add(highlightedShapeLabel);

        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static void main(String[] args) { launch(args); }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top