当前位置: 首页 > 知识库问答 >
问题:

JavaFX 2.2用于不可见节点的鼠标事件

范麒
2023-03-14

我正在尝试接收JavaFX 2.2中一个不可见节点的MouseEvents。可以把它想象成一个互动但不可见的区域,比如当鼠标悬停在它上面时,它会触发一个动作。问题是,这不是一个静态定义的区域,但有多个区域(很多)可以被应用程序移动和调整大小。所以对于我的用例来说,全局监听鼠标移动并手动检测鼠标移动事件会有很大的开销。

目前,我正在试验一个透明矩形(新矩形(200100,Color.transparent)),但实际/最终的应用程序将使用某种窗格,因为它实际上是其他组件的可拖动容器(当没有装满组件时,它具有透明区域,并且必须在这些透明区域上检测鼠标移动)。

此外,我还希望有人能帮助我更好地理解JavaFX 2.2通常是如何根据节点的可见性来处理MouseEvents的。

到目前为止,我的实验显示了以下一般见解:

>

  • 给定透明场景:当用户单击透明区域时,鼠标事件将仅传递给外部应用程序(在场景下方可见)。当用户单击场景的可见像素时,无法将鼠标事件“传递到操作系统”。正当

    默认情况下,位于其他节点顶部的窗格会吞掉任何MouseEvent,除非它是MouseTransparent或者MouseClick出现在不可见(透明)的区域。

    pickOnBounds(true|false)用于启用鼠标事件(true)基于边界(矩形)的检测或禁用它(false)。后者仅有效地处理可见像素/区域的鼠标事件。pickOnBounds(true)似乎不适用于完全不可见的节点。右?

    我的实验表明,节点至少需要填充-<code>新颜色(1,1,1.0.004)</code>才能被视为可见。较低的alpha值被认为是不可见的,这会导致不处理MouseEvents,即使调用了<code>pickOnBounds(true)</code>也是如此。

    我说得对吗?那么一个看不见的节点就没有办法接收 MouseEvents。

    或者 pickOnBounds 是否有特殊要求才能工作?我是否需要在节点显示或类似内容后才调用它?还有其他建议吗?

  • 共有1个答案

    黄修永
    2023-03-14

    简而言之:使用node . set capacity(0.0)

    不透明度属性控制节点的“视觉透明度”,而不影响它接收事件的能力,请参阅APIdocs。将此属性设置为零可实现您(和我)正在寻找的效果:一个不可见但鼠标敏感的“热区”——节点。

    这与我首先尝试的< code > node . set visible(false)形成对比。这种方法还会禁用事件处理。From Node.setVisible() APIdocs:

    不可见节点从不接收鼠标事件或键盘焦点,并且在不可见时从不保持键盘焦点。

    “不可见”实际上意味着“在调用setViable(false)之后”,不应与图像中的不透明度或全透明像素混淆。

    由于缺乏声誉,我无法直接发布屏幕截图,因此:链接到显示以下示例代码的热区布局的屏幕截图(由于明显的原因,节点的不透明度在屏幕截图中未设置为0)。

    该示例使用组作为热区,其中包含一个矩形和一个圆圈来定义捕获鼠标事件的区域。不透明度属性和鼠标处理程序只需要在组上设置,而不是在组的子项上设置。

    这样您就可以构造任意形状的热区。如果您想使用具有透明区域的图像作为热区,则需要将其picOnBound属性设置为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出现在不可见(透明)的区域。

    我也是这样理解的;但不确定鼠标是否进入/退出。对于这些,您可以至少在父级中监听<code>MOUSE_ENTERED_TARGET/MOUSE_ EXITED_TARGET</code>以确定哪个子级被输入/退出。如果要阻止子级接收事件,请在父级上注册事件筛选器并在那里使用事件。

    pickOnBounds(true |false)用于启用(true)基于边界的(矩形)鼠标事件检测或禁用(false)。后者仅有效地处理可见像素/区域的鼠标事件。

    是的。

    pickOnBounds(true)似乎不适用于完全不可见的节点。

    True用于通过调用setIn可见(true)使节点不可见。

    我的实验表明,一个节点至少需要填充-new Color(1,1,1,0.004)才能被认为是可见的。

    无可奉告,但你的实验结果似乎不错。

    那么不可见的节点将无法接收MouseEvents。

    使用.setOpacity(0.0)使节点“视觉上不可见”,但仍接收事件并遵守SetBickBounds

     类似资料:
    • 我准备好为此拔掉头发了。我正在开发游戏图形用户界面,它有一个由网格单元组成的地图。 单元格网格由StackPane组成,然后由ImageView或Shapes等组成的几个层组成。 整个内容包含在GridPane中,GridPane包含BorderPane的中心元素; 我不能在底层场景中添加鼠标事件,因为所有节点都会得到它- 下面是创建堆栈的代码: 这是设置EventHandler的代码- 谢谢你的

    • 我要在两个图像视图之间绘制路径,视图与图片相同 此路径从其中一个imageview开始(按鼠标),继续(按鼠标)并在窗格上移动事件,并且必须在另一个imageview结束(按鼠标)。这是第一次鼠标按下在imageviews上没有收到任何鼠标按下事件后的问题,该事件只是在窗格上收到,因为绘制线没有停止。我的代码出了什么问题? 这是我的控制器代码: 请帮帮我。

    • 我正在构建一个Java应用程序。这个应用程序是一个典型的“油漆”应用程序,你可以选择一种颜色,并在画布上绘制。除了...我将有一个圆圈数组分布在画布的顶部。我希望这些圆立即改变颜色,如果,当用户正在绘制和鼠标得到圆的X(10)个像素(其中X是绘制的线的宽度除以2)。 这是我的密码。我有一张画布是一组的一部分。我还创建了一个圆圈节点,并将其作为组的一部分。我想我需要以某种方式创建一个鼠标事件,当用户

    • 正在处理自定义文件上载应用程序。我有两个主要问题: 下面给出的代码不会打开Mozilla和IE的文件对话框。 在Chrome中它起作用了,但是当我第一次点击就选择文件时,它从不将文件添加到正文中。但在第二次单击时,它会将第一次单击时浏览的文件添加到正文中。 对以上问题的任何帮助都将不胜感激。

    • 在本章中,我们将详细介绍鼠标事件及其属性。 请注意:此类事件不仅可能来自于“鼠标设备”,还可能来自于对此类操作进行了模拟以实现兼容性的其他设备,例如手机和平板电脑。 鼠标事件类型 我们已经见过了其中一些事件: mousedown/mouseup 在元素上点击/释放鼠标按钮。 mouseover/mouseout 鼠标指针从一个元素上移入/移出。 mousemove 鼠标在元素上的每个移动都会触发此

    • 鼠标事件的种类 鼠标事件指与鼠标相关的事件,继承了MouseEvent接口。具体的事件主要有以下一些。 click:按下鼠标(通常是按下主按钮)时触发。 dblclick:在同一个元素上双击鼠标时触发。 mousedown:按下鼠标键时触发。 mouseup:释放按下的鼠标键时触发。 mousemove:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该