为什么我从控件边界之外的位置获取MouseDown事件?

时间:2016-07-04 13:41:26

标签: eclipse swt

我有Composite包含多个Text控件。我已将MouseListeners附加到每个控件。

令我惊讶的是,有时候,当我点击某个控件时,我会从其邻居那里收到MouseDown个事件。事件位置在控件的边界之外,我从其他控件中得不到任何我认为我点击过的事件。

是什么导致这种情况发生?

运行。按Esc键关闭MessageBox。单击BBBB字段。按Esc键关闭MessageBox。单击字段AAAA。该事件由字段BBBB生成。

public class Test
{
    public class MyListener implements MouseListener, FocusListener
    {
        private boolean active;

        @Override
        public void focusGained(FocusEvent e)
        {
            System.out.println(e);
            message((Text) e.widget, "FocusGained");
        }

        @Override
        public void focusLost(FocusEvent e)
        {
            System.out.println(e);
        }

        @Override
        public void mouseDoubleClick(MouseEvent e)
        {
        }

        @Override
        public void mouseDown(MouseEvent e)
        {
            System.out.println(e);
        }

        private void message(final Text t, final String m)
        {
            if (active == false)
            {
                active = true;
                MessageBox mb = new MessageBox(t.getShell());
                mb.setText(m);
                mb.setMessage(t.getMessage() + "\n\n" + m);
                mb.open();
                active = false;
            }
        }

        @Override
        public void mouseUp(MouseEvent e)
        {
            System.out.println(e);
            message((Text) e.widget, e.toString());
        }
    }

    private MyListener listener = null;

    public static void main(String[] args)
    {
        Display display = new Display();
        Shell shell = new Shell(display);
        new Test(shell);
        shell.open();
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    public Test(Composite parent)
    {
        listener = new MyListener();
        create(parent);
    }

    private void create(Composite parent)
    {
        parent.setLayout(new GridLayout(2, true));
        createText(parent, "AAAA");
        createText(parent, "BBBB");
        parent.layout(true);
    }

    private Text createText(Composite parent, String message)
    {
        Text t = new Text(parent, SWT.NONE);
        t.setMessage(message);
        GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
        t.setLayoutData(gd);
        t.addFocusListener(listener);
        t.addMouseListener(listener);
        return t;
    }
}

2 个答案:

答案 0 :(得分:1)

这确实很奇怪。当从B遍历到A时,MouseUp事件被标记为从字段B发送。

如果将MessageBox替换为非中断的内容,即System.out,则鼠标事件发件人是正确的。

对我而言,这似乎更像是一个理论上的极端情况。体面应用程序不会使用模态窗口中断用户字段遍历。但是,如果这与您相关,我会report a bug to SWT

答案 1 :(得分:0)

我设法通过从事件中解除弹出窗口的分离来实现这一点。 int main(int i, char**g) { int x = *g[0]; int z = *g[1]; int tmp = z ? 1 : z; return (x==0?tmp:x*tmp); } 方法现在看起来像这样:

mainCatTable.addValueChangeListener(new ValueChangeListener() {

    @Override
    public void valueChange(ValueChangeEvent event) {

        Property<Table> p = event.getProperty(); //property of valuechangeevent in this case the Table instance
        Object itemId = p.getValue(); //selected item in table. also known as "itemId"

        Property<?> containerPropertyName = mainCatTable.getContainerProperty(itemId, "HAUPTKATEGORIE");
        System.out.println("HAUPTKATEGORIE : " + containerPropertyName.getValue());

    }
});

这似乎使事件有机会继续不受弹出窗口的干扰。弹出窗口将在稍后激活。到目前为止它还可以。