Mac Java: Handling Quit, About, and Preferences menu/menubar actions

I'm just starting to get into making my Java/Swing application look and feel a lot more like a native Mac application. I've created two earlier posts on this topic already, including Making your Swing application look like a Mac application, and Putting your JMenuBar on the Mac menu bar.

The next step in the process is handling the application menu, i.e., the first menu on the Mac OS X menu bar for your application (the menu that has the About, Preferences, and Quit items on it). The next figure shows this menu for my sample application (named "WikiTeX"). You need to do a little Mac-specific coding to handling these items, but it's actually very little additional code.

The application menu on the Mac OS X menu bar

The first thing you need to do is create one or more classes to handle callbacks from these menu items. For the purposes of this example I've created one class that implements the necessary interfaces, specifically the MRJAboutHandler, MRJPrefsHandler, and MRJQuitHandler handlers, as shown below:

package com.devdaily.opensource.jelly.controller;

import javax.swing.JOptionPane;
import com.apple.mrj.MRJAboutHandler;
import com.apple.mrj.MRJPrefsHandler;
import com.apple.mrj.MRJQuitHandler;

public class MacOSXController 
implements MRJAboutHandler, MRJQuitHandler, MRJPrefsHandler
{

  public void handleAbout()
  {
    JOptionPane.showMessageDialog(null, 
                                  "about", 
                                  "about", 
                                  JOptionPane.INFORMATION_MESSAGE);
  }

  public void handlePrefs() throws IllegalStateException
  {
    JOptionPane.showMessageDialog(null, 
                                  "prefs", 
                                  "prefs", 
                                  JOptionPane.INFORMATION_MESSAGE);
  }

  public void handleQuit() throws IllegalStateException
  {
    JOptionPane.showMessageDialog(null, 
                                  "quit", 
                                  "quit", 
                                  JOptionPane.INFORMATION_MESSAGE);
    // handle exit here
    // System.exit(0);
  }

}

I'm not doing anything with these handlers, I'm just showing a dialog when each menu item is selected. Note that with the handleQuit method you're really going to want to exit your application after an "Are you sure?" prompt.

Once you have that class added to your project, you need to add the handlers somewhere during your initial setup. I did this with code like this:

MacOSXController macController = new MacOSXController();
boolean isMacOS = System.getProperty("mrj.version") != null;
if (isMacOS)
{
  MRJApplicationUtils.registerAboutHandler(macController);
  MRJApplicationUtils.registerPrefsHandler(macController);
  MRJApplicationUtils.registerQuitHandler(macController);
}

I haven't tried this on other systems yet, but I've read that if you call the registerPrefsHandler on non-Mac systems you'll have some issues, so I just put all the method calls inside the if clause.

When I run this code on my Mac system and select the About, Preferences, and Quit menu items, I do see that each of my dialogs is displayed. As an example, here's what the Preferences window looks like:

The 'preferences' window for my application.

I feel like I've got this off to a quick start, but I'm concerned that Eclipse is showing these methods as being deprecated. If that's true then this works okay for now, but it means I'm supposed to go in a different direction for the long term. I'll try to research this next. As I'm researching this it looks like the most relevant documents for running Java applications on the Mac are here:

Related posts