JavaFx:检查鼠标是否在节点的子节点上

时间:2016-01-19 21:46:03

标签: java javafx javafx-8

我想知道是否有办法确定鼠标是否与节点的子节点碰撞,换句话说,在下面的示例中,如果我单击Group,则输出为:

"Group!"

如果单击图像,则输出为:

"Group!
Image!"

有没有办法将代码放入" group.setOnMousePressed"为了检查鼠标是否在图像上并且在这种情况下不执行任何操作并执行" group.setOnMousePressed"中的内容,以便使此输出单击图像:

 "Image!"

请在下面找到一个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);
    }
}

提前谢谢

1 个答案:

答案 0 :(得分:4)

建议的解决方案:消耗事件

Consume当你在图片的点击处理程序中处理它时的鼠标事件:

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

这将阻止事件继续冒泡事件派发链。如果您需要了解这实际意味着什么,请阅读handling events上的Oracle JavaFX文档部分。

替代解决方案:检查事件目标

注意,我还在处理程序中添加了mouseEvent.getTarget()。您可以使用此调用的结果来评估事件的目标并基于此采取操作。例如,以下代码也可以使用:

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());
    }
});

以上代码的注释:

  1. 我将处理程序设置更改为一直使用onMouseClicked而不是一个onMousePressed处理程序和一个onMouseClicked处理程序。这很重要,因为鼠标点击和鼠标按下是不同的事件。
  2. 我在hBox而不是封闭组上设置了onClickHandler,因为hBox实际上是事件的目标而不是封闭组。 hBox完全覆盖了组,因此用户不能直接点击该组作为事件目标,他们只能点击覆盖的hBox。
  3. 可执行样本

    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);
        }
    }