Java, Mac OS X, and the Preferences menu item

I wrote a longer Java/Mac/Swing tutorial yesterday titled "Handling the Java on Mac OS X About, Quit and Preferences menu events", but if you're just interested in handling the Mac OS X Preferences menu item in a Java/Swing application, here's a shorter version of that information.

Extend the Mac Java ApplicationAdapter class

Step 1 in the recipe is to extend Apple's ApplicationAdapter class for Java. I do that in the following Java class named MyApplicationAdapter:

package com.devdaily.desktopshield;

import javax.swing.JOptionPane;
import com.apple.eawt.ApplicationAdapter;
import com.apple.eawt.ApplicationEvent;

/**
 * MacAdapter.java
 * Copyright 2010, Alvin J. Alexander, devdaily.com.
 * 
 * This file is part of the DesktopShield application. This class implements the 
 * Apple/Mac/Java ApplicationAdapter class, specifically the handleQuit
 * method of that class, to help shut down this application properly.
 *
 * The DesktopShield application is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The DesktopShield application is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the DesktopShield application. If not, see <http://www.gnu.org/licenses/>.
*/
public class MyApplicationAdapter extends ApplicationAdapter
{
  private DesktopShield handler;
  
  public MyApplicationAdapter(DesktopShield handler)
  {
    this.handler = handler;
  }

  public void handleQuit(ApplicationEvent e)
  {
    System.exit(0);
  }

  public void handleAbout(ApplicationEvent e)
  {
    // tell the system we're handling this, so it won't display
    // the default system "about" dialog after ours is shown.
    e.setHandled(true);
    JOptionPane.showMessageDialog(null, "Show About dialog here");
  }

  public void handlePreferences(ApplicationEvent e)
  {
    JOptionPane.showMessageDialog(null, "Show Preferences dialog here");
  }
}

As you might guess, my handlePreferences method overrides the default implementation in the Mac/Java ApplicationAdapter class.

My Java/Mac/Swing Application class

Next, somewhere near the beginning of your Java/Mac/Swing application, you need to add some lines of code like this, using Apple's Application class:

// create an instance of the Mac Application class, so i can handle the 
// mac quit event with the Mac ApplicationAdapter
Application macApplication = Application.getApplication();
MyApplicationAdapter macAdapter = new MyApplicationAdapter(this);
macApplication.addApplicationListener(macAdapter);

// need to enable the preferences option manually
macApplication.setEnabledPreferencesMenu(true);

In these lines of code we create an instance of the Mac Application class, and then construct our implementation of the ApplicationAdapter class by passing in the Application reference. Then we tell the Application instance that our adapter is the ApplicationListener/ApplicationAdapter for our application.

To handle the Preferences menu item and corresponding event, we also have to tell our Application instance to enable the Preferences menu item. If we don't add this step, the Preferences menu item will appear disabled in our application's menu.

Here's the explanation from Apple's Application javadoc about why this setEnabledPreferencesMenu step is required:

(This step) enables the Preferences item in the application menu. The ApplicationListener receives a callback for selection of the Preferences item in the application menu only if this is set to true.

Because an application may not have a preferences window, by default this is set to false, meaning that the Preferences item in the application menu is grayed out and unselectable. If a Preferences item isn't present, this method adds and enables it.

The Java/Mac/Swing Preferences menu item and event (summary)

In summary, that's really all you have to do to handle the Mac OS X Preferences menu item and event in a Java/Swing/GUI application.

Again, for a more complete discussion of handling all the typical Mac OS X application menu items, here's another link to my longer Java/Mac tutorial, which demonstrates handling these Mac Application, ApplicationAdapter, and About, Quit, and Preferences events.

Last but not least, here are links to the javadoc for Apple's Application and ApplicationAdapter classes:

Permalink

I looked at your JMenuItem example and would like to ask if you could show (if you have time) how to right justify the key stroke shortcuts under Macs.

example:

item.setAccelerator(KeyStroke.getKeyStroke('D', Event.ALT_MASK));

Under Windows the shortcuts get adjusted to the right by themselves properly, but not under Macs.

Thanks

Hmm, curious ... the accelerator key should be showing up on the right side of the drop-down menu. (I think that's what you're writing about.) I just checked my Hyde software application, which is a Java app that runs on OS X, and the menu items are on the right.

Do you have the menu items moved up to the Mac menu bar (instead of showing up on the JFrame)? If not, take a look at this info on How to move your JMenuBar to the Mac menu bar. (Sorry about the popup ads, that tutorial is on an older section of the website.) Two pages after that example, I also show how to convert [Control] keys to [Command] keys, so your app will have more of the Mac look and feel, if you need that.

Let me know if any of this does/doesn't help, and I'll see what I can do.

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.