Wie lässt sich eine Programm-Menuleiste in die Mac-Menuleiste integrieren? v.6.0

Apple stellt mit seinen Java-Extensions Schnittstellen und Klassen bereit, die spezielle Anpassungen an MacOSX ermöglichen. Das Package com.apple.eawt ist hierbei dafür zuständig, die Einbindung von Java-Applications in die native Java-Umgebung vorzunehmen.

Die Klasse des Beispiels definiert einen kleinen leeren JFrame mit einer einfachen Menuleiste, die einen Menupunkt zum Beenden der Applikation enthält.

System.getProperties().put("apple.laf.useScreenMenuBar", "true");

Die eigentliche Integration des Programm-eigenen Menus in die MacOS-Menuleiste erfolgt über diesen Eintrag in die System-Eigenschaften.
Darüber hinaus demonstriert das Beispiel wie ein programmeigener 'Über'- und ein 'Optionen'-Dialog in die Menuleiste eingebunden werden können. Eine mittlerweile als 'deprecated' deklarierte Methode hierzu kann im Beitrag MacOSX-Bibliotheken einbinden nachgelesen werden.

Im Rahmen eines Strategy-Pattern wird zur Laufzeit in der Methode getOS() das Betriebssystem abgefragt. Handelt es sich um ein MacOSX, so wird eine Instanz der Klasse MacImpl erzeugt. Sie implementiert vier Schnittstellen mit jeweils einer Methode. Die zentrale Rolle übernimmt hierbei das Interface ClassSelector, in dessen Methode handleOS() ein Application-Objekt erzeugt wird, auf dem die Handler für die o.a. Menus und das Beenden der Applikation gesetzt werden. Die Handler werden durch die anderen drei Interfaces gestellt und stellen jeweils eine entsprechende Methode bereit, in der die gewünschte Routine aufgerufen werden kann.

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import com.apple.eawt.AboutHandler;
import com.apple.eawt.AppEvent.AboutEvent;
import com.apple.eawt.AppEvent.PreferencesEvent;
import com.apple.eawt.AppEvent.QuitEvent;
import com.apple.eawt.Application;
import com.apple.eawt.PreferencesHandler;
import com.apple.eawt.QuitHandler;
import com.apple.eawt.QuitResponse;
public class MacMenuLeiste extends JFrame {

    public MacMenuLeiste() {
        JMenuBar mBar = new JMenuBar();
        JMenu fileMenu = new JMenu("Datei");
        JMenuItem quitItem = new JMenuItem("Beenden");
        fileMenu.add(quitItem);
        mBar.add(fileMenu);
        this.setJMenuBar(mBar);
        this.setSize(300, 300);
        this.setVisible(true);
    }

    public static void main(String[] args) {

        System.getProperties().put("apple.laf.useScreenMenuBar", "true");

        new MacMenuLeiste();

        if (getOS().equals("mac")) {
            //new MacImpl();
        }
    }
    
    public static String getOS() {
        String osname = System.getProperty("os.name");
        if (osname != null && osname.toLowerCase().indexOf("mac") != -1) {
            return "mac";
        }
        if (osname != null && osname.toLowerCase().indexOf("windows") != -1) {
            return "win";
        }
        return "noarch";
    }
}

class MacImpl implements ClassSelector, AboutHandler, PreferencesHandler, QuitHandler {

    public MacImpl() {
        handleOS();
    }

    public void handleOS() {
        try {
            final Application application = Application.getApplication();
            application.setAboutHandler(this);
            application.setPreferencesHandler(this);
        } catch (Throwable e) {
            System.err.println("setupMacOSXApplicationListener failed: "
                    + e.getMessage());
        }
    }

    public void handleAbout(AboutEvent arg0) {
        // new AboutDialog();
        System.out.println("handleAbout()");
    }

    public void handlePreferences(PreferencesEvent arg0) {
        // new OptionsDialog();
        System.out.println("handlePreferences()");
    }

    public void handleQuitRequestWith(QuitEvent arg0, QuitResponse arg1) {
        System.exit(0);
    }
}

interface ClassSelector {
    public void handleOS();
}

Sollte Eclipse beim Zugriff auf die Klassen des Package com.apple.eawt einen Fahler anzeigen, so muss eine Zugriffs-Regel erstellt werden. Hierzu werden als 'Resolution' 'Accessible' und als 'Rule Pattern' 'com/apple/eawt/**' eingetragen.