Das Beispiel zeigt wie ein eigenes Dock-Icon mit einer Badge eingerichtet werden kann.
Badge muss freigegeben werden
Im Beispiel wird ein kleines GUI erzeugt, das nur aus
einem JFrame
mit einem Button zum Beenden
der Application besteht. Im Dock zeigt das Programm ein
eigenes Icon, auf dem innerhalb einer Badge ein
Countdown herunterzählt.
Es muss aber beachtet
werden, dass die Badge nur bei Ausführen eines
*.app-Bundles erscheint. Wird die Klasse selbst oder
eine *.jar ausgeführt, kann zwar das Dock-Icon,
nicht jedoch die Badge angezeigt werden. Zudem muss beim
erstmaligen Aufruf der Anwendung das Anzeigen von
Mitteilungen erlaubt werden. Die Application wird
dadurch in den Systemeinstellungen unter Mitteilungen
eingetragen.
Programmaufbau
Der Konstruktor dient zum Aufruf von init()
[19]. In der Methode werden die Oberfläche und das
Dock-Icon eingerichtet. Um dessen Anzeige mit seinem
Zähler unabhängig und parallel zum
Hauptfenster zu ermöglichen, muss dies
nebenläufig erfolgen. Dies wird durch ein ExecutorService
-Objekt
gewährleistet, das einen Thread bereitstellt, in
dem showDockIcon()
aufgerufen wird [25].
Sobald sie nicht mehr benötigt werden, müssen
die dafür benötigten Resourcen durch shutdown()
wieder freigegeben werden [27].
Nicht jedes
Betriebssystem stellt eine Taskbar bereit, sodass dies
vorher durch die statische Methode Taskbar.isTaskbarSupported()
abgefragt werden sollte [24].
import java.awt.FlowLayout; import java.awt.Image; import java.awt.PopupMenu; import java.awt.Taskbar; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class MacOSXDockIconMitBadge { private static final String ICON_PATH = "/img/icon512.png"; public MacOSXDockIconMitBadge() { init(); } private void init() { ExecutorService executor = Executors.newCachedThreadPool(); if (Taskbar.isTaskbarSupported()) { executor.execute(() -> showDockIcon(15, false)); } executor.shutdown(); JButton butt = new JButton("Ende"); butt.addActionListener(e -> System.exit(0)); JFrame frame = new JFrame("Dock-Demo"); frame.setLayout(new FlowLayout()); frame.add(butt); frame.setSize(200, 80); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void showDockIcon(int number, boolean isFixed) { final Taskbar taskbar = Taskbar.getTaskbar(); if (taskbar.isSupported(Taskbar.Feature.MENU)) { PopupMenu menu = new PopupMenu("Application"); menu.add("Punkt 1"); menu.add("Punkt 2"); taskbar.setMenu(menu); } Image icon = loadImage(ICON_PATH); if ((icon != null) && taskbar.isSupported(Taskbar.Feature.ICON_IMAGE)) { taskbar.setIconImage(icon); } if (taskbar.isSupported(Taskbar.Feature.ICON_BADGE_TEXT)) { taskbar.setIconBadge(Integer.toString(number)); if (!isFixed) { while (number > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } taskbar.setIconBadge(Integer.toString(--number)); } taskbar.setIconBadge(null); } } } private Image loadImage(String imgPath) { Image img = null; try { img = ImageIO.read(getClass().getResource(imgPath)); } catch (IOException e) { System.err.println("Dock-Icon kann nicht geladen werden!"); } return img; } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new MacOSXDockIconMitBadge()); } }
Dock-Icon mit Kontextmenu
Ein Dock-Icon besitzt unter MacOS ein Kontextmenu. Es
kann durch setMenu()
der Klasse Taskbar
erweitert werden [45]. Hierzu wird der Methode eine
Instanz der Klasse PopupMenu
als Parameter
übergeben. Es enthält hier zwei Elemente, Punkt
1 und Punkt 2. Beide bleiben der
Übersichtlichkeit halber funktionslos, können
jedoch nach dem Start des Programms durch Rechtsklick
auf das Dock-Icon bewundert werden.
Optionen mit Taskbar.Feature prüfen
Um zu prüfen, ob die Menufunktion überhaupt
gegeben ist, wird die Methode isSupported()
auf dem Taskbar
-Objekt aufgerufen. Sie
liefert einen boolschen Wert abhängig von der ihr
als Parameter übergebenen Enum-Konstante vom Typ Taskbar.Feature
[41]. Das Verfahren kann für eine Reihe an
Taskbar-Prüfungen verwendet werden und wird im
vorliegenden Beispiel noch fürs Testen der
Möglichkeit zur Verwendung eines eigenen
Taskbar-Icons [48] und einer Badge mit Text-Anzeige [51]
herangezogen.
Das Setzen des Icons im Dock geschieht
nach dem Laden der Icondatei durch Aufruf von setIconImage()
auf dem Taskbar
-Objekt [49].
Einrichten der Badge
Das Hinzufügen einer Badge zum Dock-Icon wird ab
Zeile 51 demonstriert. Sie besteht aus einer kleinen
roten Kreisfläche, die das Dock-Icon
überlagert und innerhalb derer hier ein Countdown
oder wahlweise auch ein statischer numerischer Wert
angezeigt wird. Der Methode showDockIcon()
werden hierzu zwei Argumente übergeben: Das erste
ist der anzuzeigende int-Wert. Das zweite ist ein
boolscher Wert, der reguliert, ob der übergebene
numerische Wert statisch oder zum Countdown genutzt
werden soll.
Ist der Parameter isFixed
wie hier gezeigt false
, wird der
übergebene Startwert im Sekundenrhythmus
heruntergezählt und die Badge mit dem jeweiligen
Wert neu gesetzt [60]. Nach Beendigung des Countdowns
wird die Badge duch Übergabe von null
gelöscht [62].
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.