Java 如何跟踪鼠标退出/进入/悬停在组合上?

Java 如何跟踪鼠标退出/进入/悬停在组合上?,java,eclipse-plugin,swt,eclipse-rcp,mouseevent,Java,Eclipse Plugin,Swt,Eclipse Rcp,Mouseevent,下面的代码显示: 1) 使用复合时完全忽略悬停。如何启用 2) 进入/退出被跟踪,但当鼠标进入子控制区域时,父组合接收退出事件。如何使复合材料的中心区域成为复合材料的一部分 public class TryHover { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display);

下面的代码显示:

1) 使用复合时完全忽略悬停。如何启用

2) 进入/退出被跟踪,但当鼠标进入子控制区域时,父组合接收退出事件。如何使复合材料的中心区域成为复合材料的一部分

public class TryHover {

    public static void main(String[] args) {

        Display display = new Display();

        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());

        Composite composite = new Composite(shell, SWT.BORDER);
        composite.setLayout(new GridLayout(1, false));

        Label label1 = new Label(composite, SWT.BORDER);
        label1.setText("Label 1");

        Label label2 = new Label(composite, SWT.BORDER);
        label2.setText("Label 2");

        composite.addListener(SWT.MouseEnter, new Listener() {

            @Override
            public void handleEvent(Event event) {
                System.out.println("ENTER");

            }
        });

        composite.addListener(SWT.MouseExit, new Listener() {

            @Override
            public void handleEvent(Event event) {
                System.out.println("EXIT");

            }
        });

        composite.addListener(SWT.MouseHover, new Listener() {

            @Override
            public void handleEvent(Event event) {
                System.out.println("HOVER");

            }
        });

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }

    }
}
更新

是的,我同意,如果鼠标速度慢,它也会产生悬停


然后问题是关于仅进入/退出:如何打开子控件的退出?

不确定,为什么忽略悬停。我可以看到,它被跟踪了(请看屏幕截图),鼠标在复合材料上停留了至少一秒钟。您的代码未经任何修改就被使用了


也许它与操作系统有某种联系?尝试调用
composite.setEnabled(true)作为禁用的控件不会接收鼠标事件。

SWT。只有当鼠标位于
组合
上并且在几分之一秒内不移动时,才会触发鼠标悬停

SWT.MouseMove
是在将鼠标移动到组合
上时触发的

所以这真的取决于你想在这里实现什么


至于问题的第二部分:SWT不会将事件传播到小部件层次结构上(有些例外)

但是,您可以实现自己的逻辑来确定何时侦听事件

  • 对于
    SWT.MouseExit
    :获取鼠标的坐标并检查是否有任何子项包含鼠标。如果是,则什么也不做;如果不是,则留下了
    组合
  • 对于
    SWT.MouseEnter
    :这有点棘手。我想出了一个解决方案,可以跟踪当前的
    小部件
    鼠标通过屏幕上的过滤器移动。当您输入
    组合
    时,您可以检查上一个小部件是否为子部件。如果是这样,什么也不做


更新了我的答案。它应该给你一个解决问题的方法。关于第一部分。子对象的几何图形可能会出现,因此首先输入子对象将成为离开父控件的通道。如果发生这种情况,那么赛道将丢失。@SuzanCioc你能详细说明一下吗?我似乎不明白你的问题。
private static Widget mouseControl = null;

public static void main(String[] args)
{
    Display display = new Display();

    /* Overall, keep track of the Widget the mouse is moving over */
    display.addFilter(SWT.MouseMove, new Listener()
    {
        @Override
        public void handleEvent(Event e)
        {
            mouseControl = e.widget;
        }
    });

    Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final Composite composite = new Composite(shell, SWT.BORDER);
    composite.setLayout(new GridLayout(1, false));

    Label label1 = new Label(composite, SWT.BORDER);
    label1.setText("Label 1");

    Label label2 = new Label(composite, SWT.BORDER);
    label2.setText("Label 2");

    composite.addListener(SWT.MouseEnter, new Listener()
    {
        @Override
        public void handleEvent(Event event)
        {
            /* Check if the mouse was previously moving over a child (you could
             * even do recursive search here) */
            for (Control child : composite.getChildren())
            {
                if (child.equals(mouseControl))
                    return;
            }
            System.out.println("ENTER");
        }
    });

    composite.addListener(SWT.MouseExit, new Listener()
    {
        @Override
        public void handleEvent(Event event)
        {
            /* Check if the mouse is now located over a child (you could
             * even do recursive search here) */
            for (Control child : composite.getChildren())
            {
                if (child.getBounds().contains(new Point(event.x, event.y)))
                    return;
            }
            System.out.println("EXIT");
        }
    });

    composite.addListener(SWT.MouseHover, new Listener()
    {

        @Override
        public void handleEvent(Event event)
        {
            System.out.println("HOVER");
        }
    });

    shell.pack();
    shell.open();
    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
}