简而言之:使用 Node.setOpacity(0.0)
opacity 属性控制节点的“视觉透明度”,而不影响其接收事件的能力,请参阅APIdocs http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#opacityProperty。将此属性设置为零可以实现您(和我)正在寻找的效果:一个不可见但对鼠标敏感的“热区”-Node。
这与Node.setVisible(false)
我首先尝试过。该方法还会禁用事件处理。来自 Node.setVisible() API 文档:
不可见节点永远不会接收鼠标事件或键盘焦点,并且当它们变得不可见时永远不会保持键盘焦点。
“隐形”的真正意思是“调用后setVisible(false)
“并且不应与图像中的不透明或完全透明像素相混淆。
由于缺乏声誉,我无法直接发布屏幕截图,因此:链接到屏幕截图 https://i.stack.imgur.com/3Z7ae.png显示了下面示例代码的热区布局(出于明显的原因,屏幕截图中节点的不透明度未设置为 0)。
该示例使用一个 Group 作为热区,其中包含一个矩形和一个圆形来定义捕获鼠标事件的区域。只需要在 Group 上设置不透明度属性和鼠标处理程序,而不是在其子组上设置。
这样您就可以构建任意形状的热区。
如果您想使用具有透明区域的图像作为热区,则其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);
}
编辑:关于您的具体子问题(据我所知,我不是外汇专家:))
当用户单击时,无法将鼠标事件“传递给操作系统”
在场景的可见像素上。正确的?
有趣,从未尝试过。对可能有效的纯粹猜测:获取鼠标事件的屏幕坐标,将窗口移开,使用 java.awt.Robot 将操作系统光标移动到鼠标事件的坐标,如果需要,单击此处,然后移动您的窗口窗户后面。
当心:听起来完全是黑客行为!
其他节点之上的窗格默认会吞下任何 MouseEvent
除非它是 MouseTransparent 或 MouseClick 出现在
不可见(透明)区域。
我也是这么理解的;但不确定鼠标进入/退出。对于那些你可以听的人MOUSE_ENTERED_TARGET/MOUSE_EXITED_TARGET
至少在父级中确定哪个孩子进入/退出。如果您想阻止子级接收事件,请在父级上注册事件过滤器并在那里使用事件。
pickOnBounds(true|false) 可以启用(true)基于边界的
(矩形)检测 MouseEvents 或禁用它(假)。后者
仅有效处理可见像素/区域的鼠标事件。
Yes.
pickOnBounds(true) 似乎不适用于完全不可见的节点。
对于通过调用使其不可见的节点为真setInvisible(true)
.
我的实验表明,一个节点至少需要填充 - 新
颜色(1,1,1,0.004)被视为可见。
无法发表评论,但你的实验结果似乎不错。
那么不可见的节点将无法接收鼠标事件。
Using .setOpacity(0.0)
使节点“视觉上不可见”,但仍然接收事件并遵循 setbickOnBounds