当鼠标悬停在相邻节点上时,MouseEntered /退出不会被触发

时间:2015-03-30 07:31:15

标签: java javafx-3d

我有两个javafx.scene.shape.Box个实例,它们彼此相邻:

enter image description here

每当拾取的节点发生变化时,即每当鼠标进入或退出红色或蓝色节点时,我都会收到通知。

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

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

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

}

我错过了什么?

2 个答案:

答案 0 :(得分:2)

您必须将MouseListener添加到blueBoxredBox,而不是root。当您将MouseListener添加到root时,您只有在离开/进入root时才会收到通知,因此在更改root元素中的元素时没有任何事件。

答案 1 :(得分:2)

您设置了这两个框中的Group root,无论何时enterexit此组,您的活动都会被触发。多数民众赞成在发生什么。由于这两个方框都是本集团的子女,因此您不会收到通知,因为您的听众正在寻找该小组,而不是为其子女。

您可以直接在框中创建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;
});