1

这无疑是一个微不足道的问题,但我似乎无法弄清楚我做错了什么。情况很简单:我有一个应用程序,它创建了一个额外的对话框窗口来向用户显示一些东西。主应用程序有一个菜单栏,其中包含具有键盘快捷键的菜单项。当我使用键盘快捷键调用菜单项并且主程序创建新窗口时,当用户关闭新窗口并再次显示主应用程序时,菜单栏项保持突出显示/“打开”外观. 使用 SWT 4.2 复制我在 Mac OS 上看到的代码是这样的:

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

public class tester
{
    public static void createShell(Shell parent) {
        final Shell newShell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE);
        newShell.setSize(100,100);
        newShell.setLayout(new FillLayout());

        Button closeButton = new Button(newShell, SWT.NONE);
        closeButton.setText("Close");
        closeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent arg0) {
                newShell.close();
            }
        });

        newShell.open();
    }

    public static void main(String[] args) {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        shell.setSize(200, 100);

        Menu menuBar = new Menu(shell, SWT.BAR);
        shell.setMenuBar(menuBar);

        MenuItem item = new MenuItem(menuBar, SWT.CASCADE);
        item.setText("Foo");

        Menu fooMenu = new Menu(item);
        item.setMenu(fooMenu);

        MenuItem barMenu = new MenuItem(fooMenu, SWT.NONE);
        barMenu.setText("Menu item");
        barMenu.setAccelerator(SWT.MOD1 + 'F');
        barMenu.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent arg0) {
                createShell(shell);
            }
        });

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

要重现该问题,请运行上述程序,从键盘调用 Command-F,然后单击创建的窗口中的“关闭”按钮。它将关闭第二个窗口并返回原始窗口。这是我这样做后的示例:

截屏

问题是“Foo”如何保持突出显示。我希望它不会保持突出显示。事实上,如果我拉下菜单并选择菜单项,它不会保持突出显示,所以使用键盘快捷键会导致这种情况有一些特定的东西,但我正在努力弄清楚那是什么可能。

有人可以告诉我我做错了什么吗?

4

1 回答 1

1

我看不出该代码有什么问题。所以剩下的就是解决这个问题。虽然这表明存在黑客攻击,但它确实有效。这个想法是将执行推迟到稍后的时间,不是太晚,而是在足够的时间之后,以便事件完成并且项目被停用。使用的第一次测试Display.getDefault().asyncExec()没有按预期工作,所以我尝试了 with 的组合,invokeLater但这asyncExec不会有什么结果。那时我选择了一个锤子并Thread.currentThread().sleep()结合上述方法跟注,这似乎工作得很好。

所有需要改变的是SelectionAdapterbarMenu 的,如下所示:

    barMenu.addSelectionListener(new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent arg0) {
            // invoke later to give event time to finish, and have
            // the menu item deselected
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
              public void run() {
              // wait
              try { Thread.currentThread().sleep(100);} catch(Exception ex){}
              // jump back to the SWT thread and do the actual work
              Display.getDefault().asyncExec(new Runnable() {
              public void run() {
               createShell(shell);
              }});
            }});
        }
    });
于 2013-04-05T07:07:02.283 回答