Jameica kann zwar beliebig mit Plugins erweitert werden.
Diese Plugins teilen auch einen ClassPath und können
über die ServiceFactory sowie das Messaging-System
miteinander kommunizieren. Sie können jedoch nicht
die GUI eines anderen Plugins ändern. So kann z.Bsp.
Plugin A nicht die Context-Menus von Plugin B ändern
oder die Navigation eines anderen Plugins erweitern.
Dies ist jedoch sinnvoll, wenn ein Plugin durch ein
weiteres möglichst nahtlos um Funktionalität erweitert
werden soll. Sprich: Das erweiternde Plugin soll
keine eigene Navigation oder eigene Menus mitbringen
sondern stattdessen die existierenden um Funktionen
erweitern.
Genau für diesen Zweck existiert das Extension-System.
Auf der einen Seite befinden sich Komponenten, die
sich erweitern lassen (werden durch das Interface
Extandable
repräsentiert). Auf der anderen
Seite existieren Erweiterungen (müssen das Interface
Extension
implementieren), welche die
Extendables um zusätzliche Funktionalität erweitern.
Bevor eine erweiterbare Komponente (also ein Extendable) erweitert
werden kann, muss Jameica herausfinden, welche Erweiterungen überhaupt
existieren.
Bsp.: Bevor der Navigations-Baum (linkes Frame in Jameica)
gezeichnet wird, prüft Jameica für jedes Element des Baumes, ob Erweiterungen
vorliegen. Ist dies der Fall, wird jeweils deren Methode
extend(Extendable)
aufgerufen.
Eine Extension muss im System registriert sein, um angesprochen
werden zu können. Dies geschieht wiederrum automatisch (durch Definition
der Erweiterungen in der Manifest-Datei (plugin.xml)) oder manuell
durch Aufruf von ExtensionRegistry#register(Extension e, String[] extendableIDs)
).
Format der Registrierung in plugin.xml:
<plugin>
[...]
<menu>
<item id="id.menu.erweiterbar" name=...../>
</menu>
<navigation>
<item name=...../>
</navigation>
<services>
<service name=...../>
</services>
<extensions>
<extension class="name.der.java.Klasse" extends="id.menu.erweiterbar,id.extendable2,..." />
</extensions>
</plugin>
Jedes Extendable besitzt eine ID (Funktion getExtendableID()
),
über die es in ganz Jameica eindeutig identifizierbar ist.
Bevor die erweiterbare Komponente nun aktiviert wird (bei Context-Menus
ist das z.Bsp. der Moment unmittelbar vor dem Zeichnen auf dem Bildschirm)
muss sie der ExtensionRegistry Bescheid geben, dass sie nun noch erweitert
werden kann. Bsp:
public class AddressList extends ContextMenu implements Extendable
{
public AddressList()
{
addItem(new CheckedContextMenuItem(i18n.tr("Öffnen"),new AddressNew()));
addItem(ContextMenuItem.SEPARATOR);
addItem(new CheckedContextMenuItem(i18n.tr("Löschen..."), new AddressDelete()));
addItem(ContextMenuItem.SEPARATOR);
addItem(new ContextMenuItem(i18n.tr("Neue Adresse..."), new AddressNeu()));
// Uebergabe an Extension-Registry zur eventuellen Erweiterung um weitere Eintraege.
ExtensionRegistry.extend(this);
}
}