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

时间:2016-01-17 11:25:46

标签: java javafx javafx-8

JavaFx:我有一个带有Button的HBox,在一个Group中,我想为每个节点管理不同的“MousePressed”事件。 目前,如果我为所有节点处理相同的事件,它总是由父节点(组)捕获。

有办法吗? 例如,有没有办法确定鼠标坐标是否在节点的子节点上(在我的例子中是HBox)?

这是我需要的一个例子:

enter image description here

如果我点击Group我想要隐藏HBox如果鼠标的坐标不与HBox碰撞,如果我点击HBox,Hbox不需要隐藏,如果我点击按钮(实现)作为一个ImageView)我需要执行代码而不隐藏HBox。

所以我想做的就是这样:

@FXML
Group group;

” 其中group在使用sceneBuilder设计的AncorPane中 “

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>target/generated-sources/java</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

你的问题不清楚,但是,如果它对你有所帮助:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

// the magic: use setPickOnBounds(false);
public class LayersWithMouseEvents extends Application {


    @Override
    public void start(Stage primaryStage) {

        // root
        StackPane root = new StackPane();

        // layers
        Pane bottomLayer = new Pane();
        Pane topLayer = new Pane();

        // bottom: layer1, top: layer2
        root.getChildren().addAll(bottomLayer, topLayer);

        // layer 1 objects
        Rectangle rectangle = new Rectangle( 100,100,100,100);
        rectangle.setFill(Color.GREEN);
        rectangle.setOnMousePressed(e -> System.out.println("Rectangle 0: " + e));
        bottomLayer.getChildren().add(rectangle);

        // layer 2 objects
        rectangle = new Rectangle( 50,50,50,50);
        rectangle.setFill(Color.RED);
        rectangle.setOnMousePressed(e -> System.out.println("Rectangle 1: " + e));
        topLayer.getChildren().add(rectangle);

        rectangle = new Rectangle( 125,125,50,50);
        rectangle.setFill(Color.RED);
        rectangle.setOnMousePressed(e -> System.out.println("Rectangle 2: " + e));
        topLayer.getChildren().add(rectangle);

        rectangle = new Rectangle( 200,200,50,50);
        rectangle.setFill(Color.RED);
        rectangle.setOnMousePressed(e -> System.out.println("Rectangle 3: " + e));
        topLayer.getChildren().add(rectangle);

        // layer 1 event handler
        bottomLayer.setOnMousePressed(e -> System.out.println("Layer 1: " + e));

        // layer 2 event handler
        topLayer.setOnMousePressed(e -> System.out.println("Layer 2: " + e));


        // this is the magic that allows you to click on the layer1 object event though layer 2 is on top of layer 1
        // but ONLY(!) as long as the layer is transparent. if you add e. g. this it won't work anymore to click through to layer 1:
        //   layer2.setStyle( "-fx-background-color:yellow");
        topLayer.setPickOnBounds(false);

        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();

    }

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

另一个例子是将监听器添加到父级,e。 G。场景并像这样检查事件的目标:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class LayersWithMouseEvents2 extends Application {


    @Override
    public void start(Stage primaryStage) {

        Rectangle rectangle = new Rectangle( 100,100,100,100);
        rectangle.setFill(Color.GREEN);

        HBox hBox = new HBox();
        hBox.setPrefSize(200, 200);
        hBox.setStyle("-fx-background-color:yellow");
        hBox.getChildren().add( rectangle);

        Group root = new Group();
        root.getChildren().add(hBox);

        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();

        primaryStage.getScene().setOnMousePressed(e -> System.out.println("Scene: " + e));
    }

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

取决于您点击的位置:

Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = javafx.scene.Scene@2c69fd61, eventType = MOUSE_PRESSED, consumed = false, x = 295.0, y = 134.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = null, point = Point3D [x = 295.0, y = 134.0, z = 0.0], distance = 1119.6152422706632]
Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = HBox@5a40dda8, eventType = MOUSE_PRESSED, consumed = false, x = 148.0, y = 134.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = HBox@5a40dda8, point = Point3D [x = 148.0, y = 134.0, z = 0.0], distance = 1119.6152422706632]
Scene: MouseEvent [source = javafx.scene.Scene@2c69fd61, target = Rectangle[x=100.0, y=100.0, width=100.0, height=100.0, fill=0x008000ff], eventType = MOUSE_PRESSED, consumed = false, x = 52.0, y = 54.0, z = 0.0, button = PRIMARY, primaryButtonDown, pickResult = PickResult [node = Rectangle[x=100.0, y=100.0, width=100.0, height=100.0, fill=0x008000ff], point = Point3D [x = 152.0, y = 154.0, z = 0.0], distance = 1119.6152422706632]

随着可见性的切换,它可能是这样的:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class LayersWithMouseEvents2 extends Application {

    boolean hBoxVisible = true;

    @Override
    public void start(Stage primaryStage) {


        Rectangle rectangle = new Rectangle( 100,100,100,100);
        rectangle.setFill(Color.GREEN);

        HBox hBox = new HBox();
        hBox.setPrefSize(200, 200);
        hBox.setStyle("-fx-background-color:yellow");
        hBox.getChildren().add( rectangle);

        Group root = new Group();
        root.getChildren().add(hBox);

        Scene scene = new Scene(root, 800, 600);

        scene.setOnMousePressed(e -> {

            System.out.println("Scene: " + e);

            if( e.getTarget() == hBox) {
                System.out.println( "HBox clicked");
            }

            if( e.getTarget() == rectangle) {
                System.out.println( "Rectangle clicked");
            }

            if( e.getTarget() == scene) {
                System.out.println( "Scene clicked");

                hBoxVisible = !hBoxVisible;

                hBox.setVisible(hBoxVisible);}

        });

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

    }

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