简而言之:使用 Node.setOpacity(0.0)
opacity 属性控制节点的“视觉透明度”,而不影响它接收事件的能力,请参阅APIdocs。将此属性设置为零可以实现您(和我)正在寻找的效果:一个不可见但鼠标敏感的“热区”-Node.js。
这与Node.setVisible(false)
我首先尝试的相反。该方法还禁用事件处理。来自 Node.setVisible() APIdocs:
不可见节点永远不会接收鼠标事件或键盘焦点,并且在它们变得不可见时永远不会保持键盘焦点。
“不可见”实际上意味着“调用后setVisible(false)
”,不应与图像中的不透明度或完全透明像素相混淆。
由于缺乏声誉,我无法直接发布屏幕截图,因此:
链接到显示下面示例代码的热区布局的屏幕截图(由于显而易见的原因,屏幕截图中节点的不透明度未设置为 0)。
该示例使用一个 Group 作为热区,其中包含一个矩形和一个圆形来定义捕获鼠标事件的区域。只需要在 Group 上设置 opacity 属性和鼠标处理程序,而不是在子组上设置。
这样您就可以构建任意形状的热区。如果要将具有透明区域的图像用作热区,pickOnBounds
则需要将其属性设置为,false
以便考虑实际图像内容,而不仅仅是边界框。
希望能帮助到你!
public class HotZoneTest extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
Group hotZone = new Group();
root.getChildren().add(hotZone);
hotZone.getChildren().add(new Rectangle(10, 20, 100, 50));
hotZone.getChildren().add(new Circle(50, 120, 20));
hotZone.setOpacity(0.4); //set to 0.0 to make invisible
EventHandler handler = new EventHandler() {
@Override
public void handle(Event e) {
System.out.println("hotZone mouse event: " + e);
}
};
hotZone.addEventHandler(MouseEvent.MOUSE_ENTERED, handler);
hotZone.addEventHandler(MouseEvent.MOUSE_CLICKED, handler);
hotZone.addEventHandler(MouseEvent.MOUSE_EXITED, handler);
}
编辑:关于您的特定子问题(据我所知,我不是 FX 大师 :))
当用户单击场景的可见像素时,无法将鼠标事件“传递给操作系统”。对?
有意思,没试过。对可能起作用的纯粹推测:获取鼠标事件的屏幕坐标,将窗口移开,使用 java.awt.Robot 将操作系统光标移动到鼠标事件的坐标,如果需要,在那里单击,然后移动你的窗户回来。当心:听起来像一个彻头彻尾的黑客!
默认情况下,其他节点顶部的窗格将吞下任何 MouseEvent,除非它是 MouseTransparent 或 MouseClick 出现在不可见(透明)区域。
我也是这么理解的;虽然不确定鼠标进入/退出。对于那些您MOUSE_ENTERED_TARGET/MOUSE_EXITED_TARGET
至少可以在父母中聆听以确定进入/退出哪个孩子的人。如果您想阻止子级接收事件,请在父级上注册一个事件过滤器并在那里使用该事件。
pickOnBounds(true|false) 用于启用(true)基于边界(矩形)的 MouseEvents 检测或禁用它(false)。后者仅有效处理可见像素/区域的鼠标事件。
是的。
pickOnBounds(true) 似乎不适用于完全不可见的节点。
对通过调用不可见的节点为真setInvisible(true)
。
我的实验表明,一个节点至少需要填充 - new Color(1,1,1,0.004) 才能被视为可见。
无法发表评论,但您的实验结果似乎不错。
那么就没有办法让一个不可见的节点接收 MouseEvents。
使用.setOpacity(0.0)
使节点“视觉上不可见”,但仍接收事件并尊重 setbickOnBounds