2014-01-06

Ultimate Swing, Teil 30

Willkommen zurück zu einer neuen Folge meiner unendlichen Geschichte über Swing. Heute begeben wir uns in die Tiefen der privaten Teile der Klassenbibliothek. Und zwar, um dort ein wenig zu spicken…
Smiley

Notes and Tasks hat eine Eingabezeile, die mit dem Shortcut Alt-I aktiviert wird.

Screenshot von Notes and Tasks
Screenshot von Notes and Tasks

Bislang hatte ich sowohl den ausgegebenen Text als auch den korrespondierenden KeyStroke fest verdrahtet. Das ist aber fehleranfällig, wenn ich beschließe, die Auslösekombination zu ändern. Denn neben der Deklaration meiner Konstante muss ja auch der Meldungstext angepasst werden. Er wurde in eine Properties-Datei ausgelagert.

 public static final KeyStroke KEY_ALT_I = KeyStroke.getKeyStroke('I', KeyEvent.ALT_DOWN_MASK);  

Die Frage ist deshalb, ob es eine Methode gibt, die das Tastenkürzel als Klartext (String) zurück liefert. Die Klasse KeyStroke bietet nichts Passendes: toString() produziert die Ausgabe alt pressed I. Die Methoden getKeyChar(), getKeyCode() und getModifiers() liefern nur Teilinformationen. Aber da wäre noch die Klasse KeyEvent. Sie enthält unter anderem getKeyModifiersText() und getKeyText(). Leider aber auch hier kein fertiger Text.

Dass es etwas Passendes geben muss, scheint auf der Hand zu liegen. Menüeinträge zeigen ihre Shortcuts ja schließlich auch an. Wenn Sie den Quelltext von JMenuItem zücken, werden Sie dort aber nichts finden. Das Malen der Shortcuts ist nämlich Aufgabe des UI delegates. Für ein Menüelement ist deshalb eine mögliche Fundstelle in der Klasse BasicMenuItemUI versteckt. Sehen Sie sich bitte deren private Methode paintAccText() an. Acc ist hierbei die Abkürzung von Accelerator (ein Synonym für Tastenkürzel). Ihr wird (unter anderem) ein Objekt des Typs MenuItemLayoutHelper übergeben. Diese Klasse befindet sich im Paket sun.swing, ist also nicht Teil der öffentlichen API. Ihre parameterlose Methode getAccText() ist eine für uns unnötige Iteration. Die von ihr zurück gegebene Variable accText wird innerhalb der Methode reset() belegt. Damit sind wir endlich am Ziel, der leider nicht direkt aufrufbaren Methode private String getAccText(String acceleratorDelimiter).

Vielleicht fragen Sie sich nun, was uns diese Detektivarbeit bringt. Verwenden können und dürfen wir die Methode ja nicht direkt. In diesem Falle halte ich es aber für legitim, die Logik in angepasster Form als eigene kleine Hilfsmethode zur Verfügung zu stellen. Mir ist keine Klasse bekannt, die eine vergleichbare Funktionalität von Haus aus bietet. Kennen Sie eine? Melden Sie sich…

2 comments:

  1. Der Screenshot skaliert zumindestens im FF zu groß ragt in den linken Seitenbereich rein :-/ Ansonsten wie immer +1 ;-)

    ReplyDelete
    Replies
    1. Hm, das linke oder das rechte Links...? ;-)
      Habe ich korrigiert. Vielen Dank für den Hinweis.
      Viele Grüße - Thomas

      Delete