捕获,首选项和退出菜单项

时间:2015-09-05 05:04:17

标签: java cocoa menu swt

我使用当前版本的SWT来构建我的应用程序,我想在Mac OS X(Yosemite)下运行它。
我现在的问题是,我无法获得"关于","偏好"和"退出"菜单项自动添加到我的应用程序中 我已经搜索了很多,发现以下课程对我http://www.transparentech.com/files/CocoaUIEnhancer.java非常有帮助。

这是我的代码来初始化它:

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;

public class Test {
  private Display display;
  private Shell shell;

  public Test(Display display) {
    this.display = display;
    initUI();
  }

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

  private void initUI() {
    shell = new Shell(display);
    shell.setSize(808, 599);
    shell.setText("Test");

    AboutHandler aboutHandler = new AboutHandler();
    PreferencesHandler preferencesHandler = new PreferencesHandler();
    QuitHandler quitHandler = new QuitHandler();

    CocoaUIEnhancer uienhancer = new CocoaUIEnhancer("Test");
    uienhancer.hookApplicationMenu(display, quitHandler, aboutHandler, preferencesHandler);
  }

  private class AboutHandler implements Listener {
    public void handleEvent(Event e) {
    }
  }

  private class PreferencesHandler implements Listener {
    public void handleEvent(Event e) {
    }
  }

  private class QuitHandler implements Listener {
    public void handleEvent(Event e) {
    }
  }
}

我可以编译它而没有任何错误,但是如果我启动程序,那么我将得到以下异常:

Exception in thread "main" java.lang.NoSuchMethodError: actionProc
  at org.eclipse.swt.internal.Callback.bind(Native Method)
  at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
  at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
  at org.eclipse.swt.internal.Callback.<init>(Unknown Source)
  at CocoaUIEnhancer.initialize(CocoaUIEnhancer.java:124)
  at CocoaUIEnhancer.hookApplicationMenu(CocoaUIEnhancer.java:92)
  at Test.initUI(Test.java:50)
  at Test.<init>(Test.java:18)

这可能是本地图书馆的一个错误,但我无法解决这个问题!

4 个答案:

答案 0 :(得分:8)

我根本没有使用CocoaUIEnhancer,因为它也会导致问题。

所以这就是我最终在我的应用程序中所做的事情:

/**
 * Convenience method that takes care of special menu items (About, Preferences, Quit)
 *
 * @param name     The name of the menu item
 * @param parent   The parent {@link Menu}
 * @param listener The {@link Listener} to add to the item
 * @param id       The <code>SWT.ID_*</code> id
 */
private void addMenuItem(String name, Menu parent, Listener listener, int id)
{
    if (OSUtils.isMac())
    {
        Menu systemMenu = Display.getDefault().getSystemMenu();

        for (MenuItem systemItem : systemMenu.getItems())
        {
            if (systemItem.getID() == id)
            {
                systemItem.addListener(SWT.Selection, listener);
                return;
            }
        }
    }

    /* We get here if we're not running on a Mac, or if we're running on a Mac, but the menu item with the given id hasn't been found */
    MenuItem item = new MenuItem(parent, SWT.NONE);
    item.setText(name);
    item.addListener(SWT.Selection, listener);
}

只需分别使用SWT.ID_PREFERENCESSWT.ID_ABOUTSWT.ID_QUIT进行调用即可。提交后备菜单项名称,后备Menu以及要添加到菜单项的实际Listener

例如:

addMenuItem("Quit", myMenu, new Listener()
{
    @Override
    public void handleEvent(Event event)
    {
        // Close database connection for example
    }
}, SWT.ID_QUIT);

答案 1 :(得分:2)

看起来像actionProc

int actionProc( int id, int sel, int arg0 )
CocoaUIEnhancer中的

可能需要使用long而不是int来使用64位SWT的参数。

答案 2 :(得分:2)

您需要修改CocoaUIEnhancer.java,使其适用于this tutorial中描述的纯SWT应用程序:

  
      
  • 修改getProductName()方法,以便在找不到产品时返回String(而不是null)
  •   
  • 在tryWorks(IllegalStateException e)块中将代码包装在hookWorkbenchListener()中
  •   
  • 在try-catch(IllegalStateException e)块中包装modifyShells()中的代码
  •   
  • 在actionProc(...)方法中添加一些代码,打开About-Dialog和Preferences-Dialog(因为我们没有使用命令):
  •   
    static long actionProc(long id, long sel, long arg0) throws Exception {
        // ...
        else if (sel == sel_preferencesMenuItemSelected_) {
            showPreferences();
        } else if (sel == sel_aboutMenuItemSelected_) {
            showAbout();
        }
        return 0;
    }

    private static void showAbout() {
        MessageDialog.openInformation(null, "About...",
                "Replace with a proper about text  / dialog");
    }

    private static void showPreferences() {
        System.out.println("Preferences...");
        PreferenceManager manager = new PreferenceManager();
        PreferenceDialog dialog = new PreferenceDialog(null, manager);
        dialog.open();
    }


    // ...
  

最后,我们在main()方法中添加以下行:

public static final String APP_NAME = "MyApp";

public static void main(String[] args) {
    //in your case change the Test constructor 
    Display.setAppName(APP_NAME);
    Display display = Display.getDefault();

    //insert in initUI method call the earlysetup
    if (SWT.getPlatform().equals("cocoa")) {
        new CocoaUIEnhancer().earlyStartup();
    }

    Shell shell = new Shell(display);
    shell.setText(APP_NAME);
    ...
}

引用代码。

答案 3 :(得分:0)

Baz 的解决方案非常有效!如果您不想导入 OSUtils 只是为了测试您是否在 Mac 上,请改用:

System.getProperty("os.name").contentEquals("Mac OS X")