MouseEntered/Exited 悬停在相邻节点上时未触发
MouseEntered/Exited not fired when hovering over adjacent nodes
我有两个 javafx.scene.shape.Box
个彼此相邻的实例:
我希望在所选节点发生变化时收到通知,即每当鼠标进入或离开红色或蓝色节点时。
将鼠标从黑色移动到任何彩色框会正确触发 "mouse entered" 事件(反之亦然,从 red/blue 移动到黑色会触发 "mouse exited" 事件)。
但是,将鼠标从红色直接移动到蓝色(或从蓝色直接移动到红色)不会触发任何事件。
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();
}
}
我错过了什么?
您必须将 MouseListener
添加到 blueBox
和 redBox
而不是 root
。当您将 MouseListener
添加到 root
时,您只会在 leaving/entering root
时收到通知,因此在更改 root
元素内的元素时不会发生任何事件。
您设置了这两个框的 Group root
,每当您 enter
或 exit
这个组时,您的事件就会被触发。这就是正在发生的事情。由于两个框都是组的子项,您不会收到通知,因为您的听众正在寻找组,而不是它的子项。
要么你直接创建一个 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;
});
我有两个 javafx.scene.shape.Box
个彼此相邻的实例:
我希望在所选节点发生变化时收到通知,即每当鼠标进入或离开红色或蓝色节点时。
将鼠标从黑色移动到任何彩色框会正确触发 "mouse entered" 事件(反之亦然,从 red/blue 移动到黑色会触发 "mouse exited" 事件)。
但是,将鼠标从红色直接移动到蓝色(或从蓝色直接移动到红色)不会触发任何事件。
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();
}
}
我错过了什么?
您必须将 MouseListener
添加到 blueBox
和 redBox
而不是 root
。当您将 MouseListener
添加到 root
时,您只会在 leaving/entering root
时收到通知,因此在更改 root
元素内的元素时不会发生任何事件。
您设置了这两个框的 Group root
,每当您 enter
或 exit
这个组时,您的事件就会被触发。这就是正在发生的事情。由于两个框都是组的子项,您不会收到通知,因为您的听众正在寻找组,而不是它的子项。
要么你直接创建一个 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;
});