Das Beispiel zeigt den Umgang mit dem Dock- und Tray-Icon in Apples MacOS.v.6.0

Apple stellt eine eigene API für den Zugriff auf MacOS' Dock und System-Tray bereit. Die Klassen wurden bislang (≤ MacOS 10.6) von Apple mit dem Betriebssystem ausgeliefert und sollen zukünftig von Oracle weitergepflegt werden.
Das Beispiel zeigt einige Möglichkeiten, mit den Icons im Dock und im System-Tray (der oberen Leiste) umzugehen. Es ist der Übersichtlichkeit halber bewusst einfach gehalten worden. Um die Plattformunabhängigkeit von Java zu bedienen, sollte in konkreten Anwendungen das Strategy-Pattern eingesetzt werden. Ein Beispiel hierfür zeigt der Artikel 'MacOS-Bibliotheken einbinden'.

Die Klasse erzeugt ein winziges GUI, das nur aus einem JFrame mit einem Button besteht. Er dient zum Beenden der Application. Das Event-Handling hierfür wird innerhalb einer anonymen Klasse erledigt.

Um das Erstellen von Menu-Punkten zum Dock zu demonstrieren, wird in init() noch ein PopupMenu-Objekt erzeugt und dem JFrame hinzugefügt. Es enthält zwei Elemente Test und Test 2. Sie bleiben der Übersichtlichkeit halber funktionslos, können jedoch nach dem Start des Programms durch Rechtsklick auf das Dockicon bewundert werden.

Um diese und die folgenden Funktionalitäten zu erreichen reicht dies jedoch nicht aus. Hierzu muss ein Application-Objekt erstellt werden. Die Klasse ist als Singleton implementiert und erzeugt für jede Application nur ein einziges Objekt, auf dem die gewünschten Funktionalitäten erzeugt werden können. Dies gelingt logischerweise erst dann, wenn das Programm fertig gestellt worden ist, also nach Beendigung des Konstruktors. Die Methode setDockMenu() des Application-Objektes nimmt als Parameter das PopupMenu entgegen und sorgt für dessen Darstellung.

Mit der Methode setDockIconImage() der Klasse Application lässt sich ein selbst definiertes Icon für das Dock laden. Es muss als Image-Objekt zur Verfügung stehen und natürlich sauber geladen worden sein.

import java.awt.AWTException;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import com.apple.eawt.Application;

public class MacOSXDock {

    public MacOSXDock() {
        init();
    }

    private void init() {
        JButton butt = new JButton("Ende");
        butt.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        PopupMenu menu = new PopupMenu("Application");
        menu.add("Test");
        menu.add("Test 2");
        // Dockmenu erzeugen
        new Thread() {
            public void run() {
                createDock(menu);
            }
        }.start();

        JFrame frame = new JFrame("Dock-Demo");
        frame.setLayout(new FlowLayout());
        frame.add(butt);
        frame.add(menu);
        frame.setSize(200, 80);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private Image loadImage(String fileName) {
        URL url = getClass().getClassLoader().getResource(fileName);
        return new ImageIcon(url).getImage();
    }

    private void createDock(PopupMenu menu) {
        // Image laden
        Image icon = loadImage("img/cent512.png");
        // Tray-Icon setzen
        SystemTray tray = SystemTray.getSystemTray();
        TrayIcon trayIcon = new TrayIcon(icon, "Tray Demo");
        try {
            tray.add(trayIcon);
        } catch (AWTException e1) {
        }

        Application app = Application.getApplication();
        // Dock-Icon setzen
        app.setDockIconImage(icon);
        // Menu zum Dock hinzufuegen
        app.setDockMenu(menu);
        // Badge (Dock-Icon-Marke) anzeigen
        int i = 1;
        while (i < 10) {
            app.setDockIconBadge(new Integer(i).toString());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
        }
        // Badge ausblenden
        app.setDockIconBadge(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MacOSXDock());
    }
}

Dem Dock-Icon lässt sich ein sog. badge hinzufügen. Dies ist der kleine rote Punkt, den man z.B. von Mail.app kennt, wo er die Anzahl der ungelesenen Mails anzeigt. Im Beispiel wird eine Zahl beginnend bei 1 angezeigt, die sekündlich hochgezählt wird. Nach Anzeigen der 9 wird es wieder entfernt.

Das Tray-Icon ist das unter MacOS oben in der Leiste am oberen Bildschirmrand dargestellte Icon. Um es einzubinden muss das SystemTray-Objekt der Application geholt werden, mit einem Image-Objekt und einem Titel-String als Parameter ein TrayIcon erzeugt und dies schließlich dem Tray hinzugefügt werden.