JavaFx: check if the mouse is on node's children

房东的猫 提交于 2019-12-13 02:24:11

问题


I would like to know if there is a way to determine if the mouse collides with a node's children, in less words, In the example below, If I click on the Group the output is:

"Group!"

If I click on the image the output is:

"Group!
Image!"

Is there a way to put code in the "group.setOnMousePressed" in order to check if the mouse in on the image and in that case don't do anything and just execute what is in the "group.setOnMousePressed", in order to have this output clicking on image:

 "Image!"

Please find below a SSCCE:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class SSCCEForSO extends Application {



    @Override
    public void start(Stage primaryStage) {

        AnchorPane anchor= new AnchorPane();
        Group group= new Group();

        ImageView image= new ImageView();

        image.setImage(ImageUtil.getImage("wave.png"));
        ImageView image2= new ImageView();
        image2.setImage(ImageUtil.getImage("pause15.png"));
        HBox hBox = new HBox();
        hBox.setPrefSize(200, 200);
        hBox.setAlignment(Pos.CENTER);
        hBox.setStyle("-fx-padding: 10;-fx-background-color: firebrick;-fx-background-radius: 5;");

        hBox.getChildren().add( image);
        hBox.getChildren().add( image2);

        group.getChildren().add(hBox);

        group.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                System.out.println("Group!");

            }
        });

        image2.onMouseClickedProperty().set(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                System.out.println("Image!");
            }

        });


        anchor.getChildren().add(group);
        Scene scene = new Scene(anchor, 800, 600);



        primaryStage.setScene( scene);
        primaryStage.show();

    }

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

Thank you in advance


回答1:


Suggested Solution: Consume the Event

Consume the mouse event when you handle it in your on clicked handler for the image:

image2.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
        mouseEvent.consume();
        System.out.println("Image! " + mouseEvent.getTarget());
    }
});

This will prevent the event from continuing to bubble up the event dispatch chain. Read the section of the Oracle JavaFX documentation on handling events if you need to understand what this actually means.

Alternate Solution: Check the Event Target

Note, I also added mouseEvent.getTarget() to the handler. You can use the result of this call to evaluate the target of the event and take action based upon that. For example, the following code would also work:

hBox.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
        if (mouseEvent.getTarget() == hBox) {
            System.out.println("hBox! " + mouseEvent.getTarget());
        } else {
            System.out.println("hBox Ignored! " + mouseEvent.getTarget());
        }
    }
});

image2.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
        System.out.println("Image! " + mouseEvent.getTarget());
    }
});

Notes for the above code:

  1. I changed the handler settings to all consistently use onMouseClicked rather than one onMousePressed handler and one onMouseClicked handler. This is important because mouse clicks and mouse presses are distinct events.
  2. I used set the onClickHandler on the hBox rather than the enclosing group because the hBox is actually the target of the event rather than the enclosing group. The hBox covers the group completely, so the user cannot directly click on the group as an event target, they can only click on the covering hBox.

Executable Sample

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class SSCCEForSO extends Application {

    @Override
    public void start(Stage primaryStage) {

        AnchorPane anchor= new AnchorPane();
        Group group= new Group();

        ImageView image= new ImageView();

        image.setImage(new Image("http://icons.iconarchive.com/icons/custom-icon-design/pretty-social-media-2/64/Google-wave-icon.png"));
        ImageView image2= new ImageView();
        image2.setImage(new Image("http://icons.iconarchive.com/icons/custom-icon-design/pretty-office-8/64/Pause-icon.png"));
        HBox hBox = new HBox();
        hBox.setPrefSize(200, 200);
        hBox.setAlignment(Pos.CENTER);
        hBox.setStyle("-fx-padding: 10;-fx-background-color: firebrick;-fx-background-radius: 5;");

        hBox.getChildren().add( image);
        hBox.getChildren().add( image2);

        group.getChildren().add(hBox);

        group.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                System.out.println("Group!" + mouseEvent.getSource());
            }
        });

        image2.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                System.out.println("Image!" + mouseEvent.getSource());
                mouseEvent.consume();
            }
        });

        anchor.getChildren().add(group);
        Scene scene = new Scene(anchor, 800, 600);

        primaryStage.setScene( scene);
        primaryStage.show();

    }

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


来源:https://stackoverflow.com/questions/34887546/javafx-check-if-the-mouse-is-on-nodes-children

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!