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

nav*_*978 2 java javafx javafx-8

我想知道是否有一种方法可以确定鼠标是否与节点的子节点发生碰撞,简而言之,在下面的示例中,如果我单击“组”,则输出为:

"Group!"
Run Code Online (Sandbox Code Playgroud)

如果我点击图像,输出是:

"Group!
Image!"
Run Code Online (Sandbox Code Playgroud)

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

 "Image!"
Run Code Online (Sandbox Code Playgroud)

请在下面找到 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

先感谢您

jew*_*sea 5

建议的解决方案:使用事件

当您在图像的单击处理程序中处理鼠标事件时,使用鼠标事件:

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

这将防止事件继续在事件调度链中冒泡。如果您需要了解这实际上意味着什么,请阅读 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());
    }
});
Run Code Online (Sandbox Code Playgroud)

上述代码的注释:

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

可执行样本

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);
    }
}
Run Code Online (Sandbox Code Playgroud)