Command Framework

Dies ist eigentlich ein älterer Blogeintrag, aber aufgrund eines Fehlers veröffentliche ich diesen hier eben nochnals.

An einem Beispiel will ich hier mal schnell das Platform Command Framework erläutern. Dies soll als einfacher Einstieg dienen, als auch damit ich mir das komplette Thema einmal vor Augen führen kann, da ich momentan in einem relativ grossen Projekt arbeite, wo genau dieses Framework eingesetzt werden  soll.
 
Zuerst sollen an dieser Stelle einige Begriffsdefinitionen gegeben werden.
 
Command : Ein Command kann als eine abstrakte Beschreibung einer Benutzeraktion betrachtet werden. Die Benutzeraktion ist hierbei nicht mit einem Verhalten assoziiert, sondern hier geht es lediglich um die Definition eines Aktion.
 
Handler: Ein Handler ist die Implementierung des Verhaltens einer Command. Die Verknüpfung zwischen Handler und Command erfolgt hierbei über die Command-ID. In einem vorherigen Beitrag habe ichbereits auf einen interessanten IBM-Artikel zu diesem Thema verwiesen, hier können die einzlnen Begrifflichkeiten nochmals genau nachgelesen werden. Weiterhin ist im Eclipse-Magazin in der Ausgabe 02/08 ein durchaus interessanter Artikel zum Thema COmmands, der sich hauptsächlich damit beschäftigt, wie Menu-Strukturen mit Hilfe des Command-Frameworks realisiert werden können.
 
Einem Command können beliebig viele Handler zugewiesen werden, beispielsweise kann ein Command in einem bestimmten View ein komplett anderes Verhalten zugewiesen werden, als beispielsweise innerhalb der MenuBar. Ein ganz gutes Beispiel , welches hier eigentlich immer verwendet wird, ist das COPY-Command. Der Copy-Befehl hat in der MenuBar eine möglicherweise komplett andere Bedeutung als in einem TextViewer, wo beispielsweise Textpassagen kopiert werden sollen. Dies kann über 2 verschiedene Handler für ein Command realisiert werdne. Wichtig zu Beachten ist, dass zwar beliebig viele Handler einem Command zugewiesen werden können, es kann jedoch immer nur ein einziger Handler aktiv geschalten sein.
 
Was ich in diesem Artikel beschreiben möchte, ist wie man jetzt Commands richtig einsetzen kann, und ein wenig auf die Möglichkeiten des Command-Frameworks.
 
Um mit dem Command-Framework richtig arbeiten zu können,muss zusätzlich ein Blick auf die Core-Expression-Language von Eclipse geworfen werden, mit dieser lässt sich nämlich beschreiben, wann ein bestimmer Handler aktiv geschalten werden muss.
 
Um eine Expression zu definieren, definiert man eine Extension für den Extension-Point „org.eclipse.core.expressions.definitions“.
Das könnte beispielsweise so aussehen:

<extension

point=“org.eclipse.core.expressions.definitions“>

<definition

id=“myextensiondefinition“>

<with

variable=“activePartId“>

<equals

value=“myviewID“>

</equals>

</with>

</definition>

   </extension>

Diese Expression ist aktiv, wenn die variabel „activaPartId“ den Wert „myViewID“ annimmt. Dies kann beispielsweise benutzt werden, um eine Command im Menü freizuschalten, sobald ein bestimmter View geladen wird.

Die wichtigsten bereits definierten Expressions sind im Interface „ISources“ definiert, unter der URL http://wiki.eclipse.org/Command_Core_Expressions als auch im folgenden kurz erläutert.
·         activeContexts (liefert eine COllection der aktuell registrierten Kontexte)
·         activeShell (liefert die aktuelle Shell als Shell-Object)
·         activeWorkbenchWindow (liefert das aktuelle WorkbenchWindow)
·         activeEditor bzw activeEditorId (liefert den aktuellen Editor oder die aktuelle EditorID)
·         activePart bzw activePartId (s.o)
·         selection (liefert die aktuelle WorkbenchSelection)

Im folgenden sind einige Beispiele vorgestellt, die Expressions beschreiben, die folgende Expression evaluiert zu true sobald eine Properties-Datei in der Workbench selektiert wird.

<activeWhen>
   <iterate>
      <adapt type="org.eclipse.core.resources.IResource">
         <test property="org.eclipse.core.resources.name" 
               value="*.properties"/>
      </adapt>
   </iterate>
</activeWhen>
Diese Expression liefert true, sobald ein bestimmter EditorPart aktiviert wird.
<activeWhen>
   <with variable="activeEditorId">
      <equals value="myEditorId"/>
   </with>
</activeWhen>
Um eine innerhalb des Extension-Points für Expression-Definitions definierten Expression zu evaluieren, kann folgendes Fragment genuzt werden:
<activeWhen>
   <reference definitionId="meine_definition_id"/>
</activeWhen>

Um jetzt eine Command zu erstellen, muss man prinzipiell 3 Schritte durchführen (oder mehr, je nach durchzuführender Aktion).
1.  Defintion eines Commands
2.  Definition eines Handlers (oder 1..n Handlern)
3.  Definition der entsprechenden Expression, die den Handler kontextabhängig aktiviert oder deaktiviert.
Sind diese Schritte durchgeführt, hat man schon ein ganz gut laufendes Beispiel. Das wollen wir doch gleich mal probieren.

<extension

point=“org.eclipse.ui.handlers“>

<handler

class=„MyHandler“

commandId=„mycommand“>

<activeWhen>

<with

variable=“activePartId“>

<equals

value=„myview“>

</equals>

</with>

</activeWhen>

</handler>

   </extension>
Man sieht, der Handler wird über das Attribut „commandId“ an ein bestimmtes Command gehängt.
Die aktiv-schaltung per expression sollte an dieser Stelle bereits klar sein.

Um jetzt die Aktivierung bzw. Inaktivierung des Commands zu sehen, definieren wir 2 Views. Einen mit der ID „myview“, innerhalb dessen das Command aktiv sein sollte, und einen mit der ID „myOtherView“, in dem das Command nicht aktiv sein dürfte.

Um dies jetzt schön betrachten zu können, benutzen wird das Command , um einen Menüpunkt in der Anwendung zu erstellen.
Hierfür verwenden wir den Extension-Point „org.eclipse.ui.menus“.
Für diesen definieren wir eine MenuCOntribution. Das sieht prinzipiell so aus:

<extension

point=„org.eclipse.ui.menus“>

<menuContribution

locationURI=„toolbar:myview“>

<command

commandId=„mycommand“

id=„menueconttribution“

label=„Das ist mein Label“

tooltip=„Das ist mein Tooltop“>

</command>

</menuContribution>

   </extension>
Dieses Menü-Thema ist sehr schön im aktuellen Eclipse-Magazin beschrieben, weswegen ich an dieser Stelle nicht weiter darauf eingehen werden, was an dieser Stelle jedoch noch interessant ist, sind die Expressions, mit denen eine Command in verschiedenen Menü- , Toolbars etc.. gesetzt werden können, da diese Frage prinzipiell immer wieder auftaucht.
Es gibt prinzipiell die Möglichkeit, Commands in die Top-Level-Menubar, View-Toolbar, Top-Level-Toolbar o.ä.

Um eine Command in einer Menübar zu platzieren kann folgender String für die locationURI angegeben werden:
„menu:<<ID eines Elements>>“ oder „menu:org.eclipse.ui.main.menu“ für das TopLevel Menu.
Um die Command hingegen in die Toolbar zu platzieren, kann der String
„toolbar:<<ID eines Elements>>“ oder „toolbar:org.eclipse.ui.main.toolbar“ für die Top-Level-Toolbar.

In der Toolbar ist jedoch keine Standardgruppe definiert, das bedeutet, dass, bevor mit dieser MenuContribution gearbeitet werden kann, noch eine Gruppe definiert werden muss. Dies geschieht normalerweise im ApplicationActionBarAdvisor, indem man die Methode „fillCoolbar(…)“ überschreibt. Ein CodeSnippet hierfür ist

ToolbarManager manager = new ToolbarManager();
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
coolBar.add(manager);
 
Um eine Command in einem Popup zu definieren, kann folgender String verwendet werden:
„popup: <<ID eines validen Kontextes>>“ oder aber „popup: org.eclipse.ui.popup.any“, dieser sollte allerdings, wenn überhaupt, sehr sparsam verwendet werden.
Weiterhin ist http://wiki.eclipse.org/Menu_Contributions#Declarative_menus_-_some_constraints ein relativ guter Link hierzu.
 
Einen grossen Nachteil, der bisher in Menüstrukturen bestand, ist das nicht ohne weiteres kontrolliert werden konnte, an welcher Stelle eine bestimmte MenuContribution platziert wird. Dies ist mit diesem Mechanismus ohne weiteres möglich, da hier mit Paramtern die genaue Position festgelegt werden kann. Auf die genaue Funktionsweise des Menümechanismus kann hier nicht weiter eingegangen werden, aber die Platzierung sieht prinzipiell so aus:
toolbar:org.eclipse.ui.main.toolbar?after=myGroupID”, wobei die ID hinter After eine bestimmte Gruppe oder einen Separator bezeichnet.
 
Schaltet man nun zwischen 2 unterschiedlichen ViewParts hin und her, sieht man , dass die Command je nach aktivierte ViewPart aktiviert bzw. deaktiviert wird. 
Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s