Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture about, preferences and quit menu items

Tags:

java

cocoa

menu

swt

I'm using the current version of SWT to build my applications and I want to run it under Mac OS X (Yosemite).
My problem is now that I'm not be able to capture clicks on the "About", "Preferences" and "Quit" menu items which were automatically added to my application.
I already searched a lot and found the following class which seems very helpful to me http://www.transparentech.com/files/CocoaUIEnhancer.java.

And that's my code to initialize it:

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) {
    }
  }
}

I can compile it without any errors but if I start the program then I will get the following exception:

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)

It's probably an error in the native libraries but I can't figure it out!

like image 228
altralaser Avatar asked Sep 05 '15 05:09

altralaser


2 Answers

I didn't use CocoaUIEnhancer at all, as it was causing issues as well.

So here's what I ended up doing in my applications:

/**
 * 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);
}

Just call it with SWT.ID_PREFERENCES, SWT.ID_ABOUT and SWT.ID_QUIT respectively. Hand in a fallback menu item name, a fallback Menu and the actual Listener you want to add to the menu item.

So for example:

addMenuItem("Quit", myMenu, new Listener()
{
    @Override
    public void handleEvent(Event event)
    {
        // Close database connection for example
    }
}, SWT.ID_QUIT);
like image 110
Baz Avatar answered Nov 06 '22 01:11

Baz


It looks like this the actionProc

int actionProc( int id, int sel, int arg0 )

in CocoaUIEnhancer probably needs to use long rather than int for the arguments to work with 64 bit SWT.

like image 41
greg-449 Avatar answered Nov 06 '22 01:11

greg-449