Ein Command erhält zur 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. Command-Argumente sind zunächst nur eine ›flache‹ Ansammlung (Collection) von Objekten, auf die sich aus Sicht des Benutzers ein Kommando bezieht. Durch die Verwendung der losen Sammlung von Argumenten wird eine lose Kopplung erreicht. Müsste jedes Command einzeln mit genau den von ihm benötigten Argumenten versorgt werden, führte dies zu erheblichem ›Verdrahtungsaufwand‹ und einer starren Kopplung.

Die Verwaltung der Argumentliste erfordert in der Praxis häufig eine dynamische Änderung der Argumente, die Commands sehen. Zum Beispiel erfordert eine UI die Tabs benutzt beim Wechsel zwischen Tabs eine Aktualisierung der Argumentliste: Argumente, die aus dem aktiven Tab stammen, müssen entfernt und Argumente des neuen Tabs hinzugefügt werden. Darüber hinaus erfordern komplexere UIs häufig eine hierarchische Strukturierung der Argumente, zum Beispiel wenn innerhalb eines Tabs eine lokale Werkzeugleiste existiert, aber zusätzlich ein globales Menü, das einen Tab-übergreifenden Bezug hat. Zur Verwaltung dieser dynamischen und hierarchischen Argumentliste dient die Hilfsklasse Context.

In bisherigen Versionen musste beziehungsweise konnte der Context manuell verwaltet, das heißt per new Context(...) erstellt und gehalten werden. Dabei wurde manuell eine Kontexthierarchie erzeugt (durch Erzeugung von Contexten sowie durch manuelles Setzen der Eltern-Kind-Bezüge zwischen denselben). Es existierten zwar Methoden, um Contexte mit Komponenten zu assoziieren, deren Verwendung war aber optional. Die manuelle Verwaltung wird in Jadice 5 nicht mehr unterstützt, da sie zu äußerst verwirrenden und schwer wartbaren Konstruktionen führen konnte. Stattdessen folgt nun die Kontext-Hierarchie automatisch der Komponentenhierarchie der GUI. Hierbei muss nicht zwingend jedes GUI-Element einen eigenen Context bekommen. Vielmehr genügt es, an ›neuralgischen Punkten‹, das heißt an Stellen, an denen die GUI dynamisch veränderbar ist, Contexte zu installieren. In einfachen Fällen genügt es damit, einen Top-Level-Context pro Frame zu erstellen.

Die Verwaltung der Contexte erfolgt mittels folgender Methoden:

Die Sichtbarkeit von Argumenten innerhalb der Context-Hierarchie wird über Aggregationsregeln gesteuert, die bei der Installation des Context 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. Folgende Aggregationsregeln sind möglich:

Kontexte können aktiv oder inaktiv sein. Dadurch wird dem Umstand, dass GUI-Elemente aktiv oder inaktiv sein können, Rechnung getragen. So ist zum Beispiel der Context eines inaktiven (also nicht sichtbaren) Tabs inaktiv, während der Context des aktiven Tabs selbst ebenfalls aktiv ist. Die Aktivität von Contexten kann manuell über Context.setActive(boolean active) verwaltet werden. Dies ist jedoch nicht notwendig für JTabbedPanes sowie JDesktopPanes, da für diese beiden häufig verwendeten Komponententypen die Aktivierung derer Contexte automatisch erledigt wird. Es genügt hierzu, der JTabbedPane beziehungsweise JDesktopPane einen Context zu installieren.

In Version 4 bot der Context noch einige Hilfsmethoden, mit denen Argumente bestimmten Typs im Context gesucht werden konnten. Im Sinne einer übersichtlicheren API haben wir diese Methoden als statische Methoden in ContextUtils ausgelagert. So erhalten Sie zum Beispiel durch Aufruf von ContextUtils.findFirst(myContext, PageView.class) die erste Instanz eines PageViews, die beim Durchsuchen des Contexts gefunden wird. Die Methoden von ContextUtilserlauben es auch, den Inhalt von Contexten zu befragen, ohne zunächst den betreffenden Context zu ermitteln. So erlaubt es zum Beispiel ContextUtils.findFirst(myJComponent, PageView.class) einen PageView zu ermitteln, der sich in einem für myJComponent zuständigen Context befindet.

Darüber hinaus stehen in den ContextUtilsweitere Hilfsmethoden zu Verfügung, die die Bearbeitung des Inhalts eines Contexts vereinfachen. ContextUtils.replace(myJComponent, PageView.class, myPageView) ersetzt zum Beispiel alle eventuell im Context der gegebenen Komponente enthaltenen PageViews durch die gegebene neue PageView-Instanz.

Wollten bisher Commands mit Argumenten arbeiten, die ihnen über eine Argumentliste (in Form eines Contexts oder einer simplen Collection) bereitgestellt wurden, so mussten sie sich verschiedener Filtermethoden bedienen, die in der abstrakten Superklasse AbstractCommand bereitgestellt wurden. Dies war umständlich und fehlerträchtig. In Version 5 haben wir deshalb die Möglichkeit geschaffen, Argumente per Injection automatisch ›bestücken‹ zu lassen. Dadurch werden künftig viele Arbeitsschritte durch das Framework übernommen, sodass für ein Command benötigte Objekte im Regelfall automatisch bereit stehen. Aufgabe des Integrators ist es, den Context initial mit den benötigten Objekten zu befüllen und für jedes Command zu definieren, welche Objekte es aus dem Kontext voraussetzt. Dass diese Objekte tatsächlich zur Verfügung stehen, musste bisher in jedem Command manuell überprüft werden. Diese Arbeit wird künftig durch das Framework übernommen. Nur noch in Ausnahmefällen ist es notwendig, den Kontext selbst zu befragen.

Sollte dieser Fall auftreten, kann auf die Kontextobjekte über die statischen Methoden in ContextUtils zugegriffen werden.

[jadice® document platform 5 Dokumentation. Erstellungsdatum: 2011-08-12]
loading table of contents...