2

我有两个javafx.scene.shape.Box彼此相邻放置的实例:

在此处输入图像描述

我想在选择的节点发生变化时得到通知,即鼠标进入或退出红色或蓝色节点时。

将鼠标从黑色移动到任何彩色框都会正确触发“鼠标进入”事件(反之亦然,从红色/蓝色到黑色会触发“鼠标退出”事件)。

但是,将鼠标从红色直接移动到蓝色(或从蓝色直接移动到红色)不会触发任何事件。

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.stage.Stage;

public class Demo extends Application {

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

    @Override
    public void start(Stage stage) {
        Box redBox = new Box(100, 100, 100);
        redBox.setId("red");
        redBox.setMaterial(new PhongMaterial(Color.RED));
        redBox.setTranslateX(100);
        redBox.setTranslateY(100);
        redBox.setTranslateZ(20);

        Box blueBox = new Box(100, 100, 100);
        blueBox.setId("blue");
        blueBox.setMaterial(new PhongMaterial(Color.BLUE));
        blueBox.setTranslateX(200);
        blueBox.setTranslateY(100);
        blueBox.setTranslateZ(20);

        PointLight pointLight = new PointLight(Color.ANTIQUEWHITE);
        pointLight.setTranslateX(800);
        pointLight.setTranslateY(-100);
        pointLight.setTranslateZ(-1000);

        Group root = new Group(redBox, blueBox);
        root.getChildren().add(pointLight);

        root.setOnMouseEntered(me -> {
            System.out.println("Entered " + resolvePickedId(me));
        });

        root.setOnMouseExited(me -> {
            System.out.println("Exited " + resolvePickedId(me));
        });

        Scene scene = new Scene(root, 300, 200, true);
        scene.setFill(Color.rgb(10, 10, 40));
        scene.setCamera(new PerspectiveCamera(false));
        stage.setScene(scene);
        stage.show();
    }

    private static String resolvePickedId(MouseEvent me) {
        Node intersectedNode = me.getPickResult().getIntersectedNode();
        return intersectedNode == null ? "(none)" : intersectedNode.getId();
    }

}

我错过了什么?

4

2 回答 2

2

您必须添加一个MouseListenertoblueBoxredBox而不是root. 当您添加时MouseListenerroot您只会在离开/进入时收到通知,root因此在更改元素内的root元素时不会发生任何事件。

于 2015-03-30T07:37:26.540 回答
2

您设置了Group root这两个盒子中的一个,无论何时您enterexit该组,您的事件都会被触发。这就是正在发生的事情。由于这两个框都是 Group 的子项,因此您不会收到通知,因为您的 Listener 正在寻找该组,而不是它的子项。

您可以直接为这些框创建一个MouseListener,也可以执行诸如跟踪当前节点并检查OnMouseMoved更改之类的操作:

//in the class, new variable
Node save = null;

//.... in the start method

root.setOnMouseEntered(me -> {
    System.out.println("Entered " + resolvePickedId(me));
    save = me.getPickResult().getIntersectedNode();
});

root.setOnMouseMoved(me ->{
    if(me.getPickResult().getIntersectedNode() != save){
        System.out.println("Changed to "+resolvePickedId(me));
        save = me.getPickResult().getIntersectedNode();
    }
});

root.setOnMouseExited(me -> {
    System.out.println("Exited " + resolvePickedId(me));
    save = null;
});
于 2015-03-30T07:38:58.583 回答