Configuring the OS-X application menu for SWT apps

Configuring the OS-X application menu for SWT apps

If you write a ‚pure‘ SWT application on the Mac (i.e. just SWT — no RCP/workbench), you will notice that the OS-X application menu is not properly configured. It just displays ‚SWT‚ instead of the application name. Furthermore, the ‚About SWT‚ and ‚Preferences…‚ menu entries have no effect.

The remainder of this blog explains how to fix this:

The first thing to notice is that regular RCP applications do not have this issue. After exploring the code, you will discover the org.eclipse.ui.cocoa fragment, which provides Mac-specific customizations to the org.eclipse.ui bundle.

To configure the OS-X application menu, we copy the following files from org.eclipse.ui.cocoa into our project:

  • CocoaUIEnhancer.java
  • CocoaUtil.java
  • SWTCocoaEnhancerDelegate.java
  • Messages.properties

We then modify CocoaUIEnhancer.java, to make it work with pure SWT applications (it assumes we are running a workbench, which is not the case):

  1. Modify the getProductName() method to return a String when no product is found (instead of null)
  2. Wrap the code in hookWorkbenchListener() in a try-catch (IllegalStateException e) block
  3. Wrap the code in modifyShells() in a try-catch (IllegalStateException e) block
  4. Add some code to the actionProc(...) method, to bring up an About-Dialog and Preferences-Dialog (since we aren’t using commands):
        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();
	}

Finally, we add the following lines to our main() method:

	public static final String APP_NAME = "MyApp";

	public static void main(String[] args) {
		Display.setAppName(APP_NAME);
		Display display = Display.getDefault();

		if (SWT.getPlatform().equals("cocoa")) {
			new CocoaUIEnhancer().earlyStartup();
		}

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

To try it, download the complete sample project.

If you like this, follow me on twitter,
Elias.