为什么 MouseDown 事件的坐标与 MenuDetect 事件的坐标不同?

Why are the coordinates of a MouseDown event different from a MenuDetect event?

背景:我正在尝试以编程方式在 SWT Table 上创建上下文菜单。我以编程方式执行此操作,因为我需要 hide/show 基于单击的单元格而不是行项目的菜单。

我计划使用事件 class 中的 x,y 坐标来查找被单击的单元格,因此我捕获了未键入的 MouseDown 事件和未键入的 MenuDetect 事件。我将日志消息放入事件处理程序中,这样我就可以更好地了解发生了什么。这是我的代码:

    tree.addListener(SWT.MouseDown, new Listener() {
        @Override
        public void handleEvent(final Event event) {
            System.out.println("Mouse down: (" + event.x + ", " + event.y + ")");
            handleMouseDown(event);

        }
    });
    tree.addListener(SWT.MenuDetect, new Listener() {
        @Override
        public void handleEvent(final Event event) {
            System.out.println("Menu Detect: (" + event.x + ", " + event.y + ")");
            handleMenuDetect(event);

        }

    });

同样的点击,我希望看到相同的结果,然而,当我点击一列单元格时,我的输出如下:

Mouse down: (334, 11) Menu Detect: (1270, 255)

Mouse down: (331, 37) Menu Detect: (1267, 281)

Mouse down: (329, 55) Menu Detect: (1265, 299)

Mouse down: (324, 77) Menu Detect: (1260, 321)

Mouse down: (324, 100) Menu Detect: (1260, 344)

这是怎么回事?他们指的不是同一个点吗?他们在计算来自不同来源的 x,y 吗?

Are they calculating the x,y from different origins?

是的,他们有。

SWT.MenuDetect事件位置是基于整个屏幕的鼠标位置,而SWT.MouseDown事件位置是基于其合成的。

这意味着一个告诉您事件在屏幕上的哪个位置发生,而另一个告诉您它在小部件中的哪个位置发生。

要使它们使用相同的坐标系(小部件的系统),请调用 Control#toControl(int, int) 进行映射。

tree.addListener(SWT.MouseDown, (e) -> {
    System.out.println(new Point(e.x, e.y));
});
tree.addListener(SWT.MenuDetect, (e) -> {
    System.out.println(tree.toControl(e.x, e.y));
});

Control#toDisplay(int, int) 会做相反的事情。


供参考:

MouseEvent Javadoc:

public int x

the widget-relative, x coordinate of the pointer at the time the mouse button was pressed or released

MenuDetectEvent Javadoc:

public int x

The display-relative x coordinate of the pointer at the time the context menu trigger occurred.