Der Kontext (Context
)
Instanzen der Klasse Context
bilden die Brücke zwischen
GUI-Elementen, Aktionen und Kommandos.
Kommandos benötigen zu ihrer Ausführung eine Anzahl von Objekten, Argumente genannt, die den Zustand der Benutzeroberfläche zum Zeitpunkt der Ausführung der Aktion widerspiegeln. Zu dieser Anzahl von Objekten kann jedes GUI-Element eigene Objekte beisteuern, sodass letztlich eine Ansammlung von Objekten entsteht, auf die sich aus Sicht des Benutzers ein Kommando bezieht. Diese Ansammlung wird Kontext genannt.
Im Besonderen können auch GUI Elemente als semantische Einheiten verstanden und der Sammlung hinzugefügt werden. Ein Beispiel: Ein Fenster beinhaltet eine Viewerinstanz, eine Menüleiste und eine Werkzeugleiste. Jede Aktion, die innerhalb dieses Fensters passiert, kann Auswirkungen auf den Zustand (enabled state), aber auch auf die Art der Ausführung der Werkzeuge in der Werkzeugleiste oder der Menüeinträge in der Menüleiste haben. Ebenso können aber auch die Werkzeuge oder Menüeinträge mit Objekten des Fensters arbeiten. Damit bildet das Fenster in sich eine logische Einheit, dessen einzelne Elemente in ihrem Zustand und ihrer Ausführbarkeit voneinander abhängen.
In komplexeren Anwendungen ist es oft sinnvoll, mehr als einen Kontext zu nutzen. Diese können entweder unabhängig voneinander sein oder Zugriff auf die Elemente anderer Kontexte haben. Wie die Sichtbarkeit festgelegt werden kann, wird weiter unten erläutert.
Instanzen von Context
sind stets einer GUI-Komponente
zugeordnet. Da die grafische Benutzeroberfläche eine Objekthierarchie bildet,
unterstützen auch Kontexte die hierarchische Anordnung. Soll der im Beispiel
beschriebenen Oberfläche ein weiterer Viewer hinzugefügt werden, der eine eigene
Werkzeugleiste mitbringt und von den anderen Komponenten unabhängig ist, kann zu
diesem Zweck ein weiterer, unabhängiger Kontext angelegt werden, der lediglich
dem zweiten Viewer und seiner Werkzeugleiste zugeordnet wird.
Es ist nicht zwingend notwendig, jedes GUI-Element mit
einem eigenen Kontext zu versehen. Vielmehr wird zusammengehörigen Elementen ein
gemeinsamer Kontext zugewiesen. Hat eine Oberflächenkomponente keinen ihr eigens
zugewiesenen Kontext, wird jenes Context
-Objekt verwendet, das bei
Durchsuchen der Komponentenhierarchie zur Wurzel hin als erstes auftaucht. Für
weniger komplexe Benutzeroberflächen genügt es somit, einen einzigen Kontext für
die RootPane des beinhaltenden Fensters zu registrieren.
In umfangreicheren Benutzeroberflächen ist es häufig der Fall, dass nur Teile
der gesamten Applikation gleichzeitig sichtbar sind. Dieser Zustand tritt
beispielsweise dann ein, wenn JTabbedPane
s zur
Präsentation verwendet werden: Sämtliche GUI-Elemente, die
sich auf ausgeblendeten Tabs befinden, sind inaktiv. Die Implementierung von
Context
unterstützt dieses Konzept, indem auch jeder einzelne Kontext aktiv
oder inaktiv gesetzt werden kann. Auf einer gegebenen Instanz geschieht dies
über die Methode setActive(boolean active)
. Im Regelfall
muss dieser Aufruf manuell erfolgen. Die häufig verwendeten Komponententypen
JTabbedPane
sowie JDesktopPane
bilden jedoch eine Ausnahme, da die Aktivierung ihnen zugeordneter Kontexte
durch das Framework automatisch vorgenommen wird.
Notwendig wird die Funktion zur Deaktivierung von Kontexten dort, wo eine
Kontexthierarchie existiert, in der die einzelnen Context
-Objekte nicht
unabhängig voneinander sind.
Die Abhängigkeit einzelner Context
-Objekte voneinander und damit auch die
Sichtbarkeit von Kontextinhalten innerhalb der Hierarchie wird über sogenannte
Aggregationsregeln gesteuert, die bei der Erstellung des Kontexts angegeben
werden. Wird ein Context
nach dem in ihm enthaltenen Argumenten befragt, so
werden zunächst die Argumente, die dem betreffenden Context
selbst
hinzugefügt wurden, geliefert. Darüber hinaus können aber auch Argumente von
über- oder untergeordneten Kontexten sichtbar werden. Die Sichbarkeitsangaben
werden gesteuert über die Werte der Enumerationen Context.Ancestors
und
Context.Children
. Folgende Aggregationsregeln sind möglich:
Ancestors.NONE
: Elemente von übergeordneten Kontexten sind niemals sichtbarAncestors.ALL
: Die Elemente aller übergeordneten Kontexte sind sichtbar. Dies bezieht sich jedoch nur auf die Elemente der übergeordneten Kontexte selbst, nicht auf die derer Kindkontexte, unabhängig davon, welche Aggregationsregeln diese benutzen. Elemente von Geschwisterkontexten werden also niemals sichtbar.Ancestors.PARENT
: Die Elemente des direkt übergeordneten Kontexts sind sichtbar, nicht aber die von dessen Kindern.Children.NONE
: Elemente von untergeordneten Kontexten sind niemals sichtbar.Children.ALL
: Die Elemente aller untergeordneter Kontexte sind sichtbar, unabhängig davon, ob diese aktiv oder inaktiv sind.Children.ACTIVE
: Die Elemente der aktiven untergeordneten Kontexte sind sichtbar.
Die Verwaltung der Kontexte erfolgt mittels folgender Methoden:
static Context.install(JComponent component, Children ca, Ancestors aa)
erzeugt einenContext
und verbindet ihn mit der gegebenen Komponente. Im Falle des Top-Level-Kontext sollte dieser an der ContentPane desJFrame
s installiert werden. Verknüpfungen zu bereits vorhandenen Kontexten in der Hierarchie werden automatisch erstellt.static Context.get(JComponent component)
liefert denContext
, der für die gegebene Komponente zuständig ist. Hierzu wird die Komponentenhierarchie, ausgehend von der gegebenen Komponente nach oben hin durchsucht und der Kontext der ersten Komponente, auf der ein Kontext installiert wurde, zurückgegeben.static Context.getPrivateContext(JComponent component)
liefert denContext
der Komponente, sofern auf ihr ein Kontext installiert wurde. Andernfalls wirdnull
zurückgegeben. Eine Suche findet also nicht statt.
Instanzen der Klasse Context
informieren registrierte Interessenten
(ContextListener
) über Änderungen des Kontexts. Dies betrifft Änderungen an
den enthaltenen Objekten, aber auch semantische Änderungen des Kontexts, die
provoziert werden können durch einen Aufruf der Methode
contextChanged()
.
In manchen Fällen ist es notwendig, auf die Objekte eines Kontexts gezielt
zuzugreifen. Die Klasse ContextUtils
bietet zu diesem Zweck eine Sammlung
statischer Hilfsmethoden, die folgende Aufgaben erfüllen:
Hinzufügen von Objekten
Löschen von Objekten
Ersetzen von Objekten
Suchen von Objekten
Ermitteln der Anzahl von Objekten im Kontext.
Die meisten Methoden existieren in zwei Ausprägungen. Die erste akzeptiert ein
Context
-Objekt auf dem die gewünschte Operation ausgeführt wird. Der zweiten
wird eine JComponent
übergeben. In diesem Fall wird der
gültige Kontext automatisch identifiziert und für die Ausführung der Operation
verwendet.