Java 在GTK中,SWT.ON_TOP在.setfocus()上导致不可预测的行为

Java 在GTK中,SWT.ON_TOP在.setfocus()上导致不可预测的行为,java,eclipse-plugin,gtk,swt,Java,Eclipse Plugin,Gtk,Swt,以下是我想要实现的目标: 在某些触发器上(此处:单击按钮),应该会出现浮动工具栏。在此之后,焦点仍应放在文本输入字段上 单击浮动工具栏中的按钮时,焦点应保留在文本输入字段中 浮动工具栏应通过始终位于顶部的外壳实现 通过在调用text.setFocus(基于)的覆盖shell上引入ShellListener,我实现了(1) 通过在按钮上保留一个MouseListener,并在单击时调用text.setFocus,我实现了(2) 现在,我的问题是,每个解决方案都可以独立工作。然而,当我同时使用两个侦

以下是我想要实现的目标:

  • 在某些触发器上(此处:单击按钮),应该会出现浮动工具栏。在此之后,焦点仍应放在文本输入字段上
  • 单击浮动工具栏中的按钮时,焦点应保留在文本输入字段中
  • 浮动工具栏应通过始终位于顶部的
    外壳实现

    通过在调用
    text.setFocus
    (基于)的覆盖shell上引入
    ShellListener
    ,我实现了(1)

    通过在按钮上保留一个
    MouseListener
    ,并在单击时调用
    text.setFocus
    ,我实现了(2)

    现在,我的问题是,每个解决方案都可以独立工作。然而,当我同时使用两个侦听器时(如下面的MWE),我会出现奇怪的行为:

    • 显示覆盖壳后,文本字段将正确聚焦
    • 单击覆盖外壳中的按钮不会将焦点返回到文本字段,除非
      • 通过单击主shell中的任意位置,可以手动聚焦主shell
      • 您可以在叠加外壳中的按钮上进行垃圾邮件单击,在随机单击一定数量后,文本输入会正确聚焦,然后每次连续单击都会正确聚焦
    这似乎是Ubuntu(GTK)特有的问题。我使用的是SWT4.16

    考虑以下MWE

    请注意,如果我们省略顶部的SWT,并将其替换为SWT.SHELL TRIM,则一切正常

    奇怪的是,在SWT.ON_TOP的情况下,
    overlayShell上的
    shellActivated
    并不总是在单击覆盖shell中的按钮时触发,而且当它触发时,它与正确转移的焦点不一致

    import org.eclipse.swt.swt;
    导入org.eclipse.swt.events.FocusEvent;
    导入org.eclipse.swt.events.FocusListener;
    导入org.eclipse.swt.events.MouseEvent;
    导入org.eclipse.swt.events.MouseListener;
    导入org.eclipse.swt.events.ShellEvent;
    导入org.eclipse.swt.events.ShellListener;
    导入org.eclipse.swt.layout.GridData;
    导入org.eclipse.swt.layout.GridLayout;
    导入org.eclipse.swt.layout.RowLayout;
    导入org.eclipse.swt.widgets.Button;
    导入org.eclipse.swt.widgets.Composite;
    导入org.eclipse.swt.widgets.Display;
    导入org.eclipse.swt.widgets.Event;
    导入org.eclipse.swt.widgets.Listener;
    导入org.eclipse.swt.widgets.Shell;
    导入org.eclipse.swt.widgets.Text;
    不带标题的公共类外壳2{
    公共静态void main(字符串[]args){
    最终显示=新显示();
    最终外壳主外壳=新外壳(显示器、SWT、外壳和装饰);
    主机壳。设置尺寸(300200);
    setLayout(新的GridLayout());
    mainShell.open();
    文本文本=新文本(mainShell,SWT.BORDER);
    最终外壳覆盖层外壳=新外壳(显示器,顶部的SWT);
    设置大小(150150);
    覆盖层设置位置(400200);
    setLayout(新的GridLayout());
    //(1)首次打开叠加壳时返回焦点
    addShellListener(新的ShellListener(){
    @覆盖已激活的公共无效外壳(外壳事件arg0){
    setFocus();
    }
    @重写公共无效shellClosed(ShellEvent arg0){}
    @重写公共无效shellDeactivated(ShellEvent arg0){}
    @重写公共无效shellDeiconified(ShellEvent arg0){}
    @重写公共无效ShellIconnified(ShellEvent arg0){}
    });
    按钮=新按钮(主外壳,SWT.按钮);
    button.setText(“打开覆盖层”);
    button.AddMouseStener(新的MouseStener(){
    @重写公共void mouseDoubleClick(MouseEvent e){}
    @重写公共void mouseDown(MouseEvent e){}
    @重写公共无效mouseUp(MouseEvent e){
    overlyshell.setVisible(true);
    }
    });
    Button buttonInOverlay=新按钮(overlayShell,SWT.PUSH | SWT.BORDER);
    buttonInOverlay.setText(“foo”);
    //(2)单击叠加中的按钮时返回焦点
    //这似乎只有在覆盖外壳时才起作用(随机,类似于竞争条件)
    //在顶部有SWT。如果没有,则没有效果。
    buttonInOverlay.addMouseListener(新的MouseListener(){
    @重写公共void mouseDoubleClick(MouseEvent arg0){}
    @重写公共void mouseDown(MouseEvent arg0){}
    @重写公共void mouseUp(MouseEvent arg0){
    布尔值didSetFocus=text.setFocus();
    //值得注意的是,即使没有有效地设置焦点,情况也是如此
    }
    });
    //设置事件循环。
    而(!mainShell.isDisposed()){
    如果(!display.readAndDispatch()){
    //如果事件队列中没有更多条目
    display.sleep();
    }
    }
    display.dispose();
    }
    }
    
    我已经开始逐步阅读SWT源代码,但我对它感到相当困惑。有人知道是什么导致了这个奇怪的问题吗