A l'étape du billet précédant [step5] notre éditeur de workflow est constitué de pages UI (générées par EMF.Edit) et d'une page source (basée sur un StructuredTextEditor WST). Dans ce billet, nous allons ajouter une page graphique à notre éditeur de workflow en utilisant le projet GEF. La page graphique permettra de gérer graphiquement :

la description du workflow XML :
<workflow>
<state name="state1" />
<state name="state2" />
<action fromState="state1" toState="state2" name="action1" />
</workflow>
A la fin du billet nous aurons initialisé une page graphique Graphics vierge (avec une palette d'outils vide) basée sur GEF :

Vous pouvez télécharger le projet org.example.workflow_step6.zip présenté dans ce billet.
Le projet GEF qui signifie Graphical Editing Framework fournit un framework qui permet de développer son propre éditeur graphique complexe permettant de gérér (graphiquement) son modèle (modèle Java, EMF, DOM XML..). Dans notre cas le modèle géré sera notre instance EMF WorkflowType.
Lorsque j'ai démarré GEF, je ne savais pas par où commencer, et il m'a fallu un temps considérable pour assimiler le framework (et j'ai encore beaucoup à apprendre) dù à sa grande richesse de fonctionnalités. Si vous êtes débutant en GEF je vous conseille de lire les tutoriaux en francais sur GEF sur le blog de Psykokwak. Il décrit pas à pas comment développer un éditeur graphique basé sur GEF dans une application RCP. La partie modèle se base sur un POJO simple et la partie sérialisation du modèle n'est pas spécialement traité, par contre il montre tout ce que peut fournir GEF. Je vous conseille vivement de lire ces billets pour comprendre les différents composants de GEF (GraphicalEditor, PaletteRoot...).
Dans mes billets je vais moi aussi tenter d'expliquer GEF en décrivant pas à pas à comment développer la page graphique de l'éditeur de workflow.
La documentation officiel de GEF propose plusieurs articles sur lequels je me suis appuyé :
Mais je vous avoue que j'ai du lire plusieurs fois ces articles et mettre les mains dans le code pour comprendre les principes de GEF. GEF est un super framework mais qui demande beaucoup d'investissements (comme EMF ou d'autres frameworks).
Dans ce billet nous allons initialiser la page GEF en :
ajouter la dépendance org.eclipse.gef au projet org.example.workflow.editor.
GEF fournit la classe abstraite org.eclipse.gef.ui.parts.GraphicalEditor qui éténd la classe abstraite org.eclipse.ui.part.EditorPart (classe de base pour les éditeurs). Au lieu d'étendre directement GraphicalEditor nous allons éténdre GraphicalEditorWithFlyoutPalette (qui éténd GraphicalEditor) pour bénéficier d'une palette d'outils. Un outil permet de manipuler le graphique (ex : sélection de figures du graphique) ou de modifier le modèle (outil de création de figures).
Dans la dernière section GraphicalEditor, vous pourrez voir une copie d'écran pour chaque implémentation de GraphicalEditor fournit par GEF.
Créer la classe org.example.workflow.presentation.graphical.GraphicalWorkflowEditor comme suit :
package org.example.workflow.presentation.graphical;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
public class GraphicalWorkflowEditor extends GraphicalEditorWithFlyoutPalette {
@Override
protected PaletteRoot getPaletteRoot() {
return null;
}
@Override
public void doSave(IProgressMonitor monitor) {
}
}
La classe GraphicalEditorWithFlyoutPalette impose d'implémenter les méthodes GraphicalEditorWithFlyoutPalette#getPaletteRoot() et GraphicalEditorWithFlyoutPalette#doSave(IProgressMonitor monitor) qui a ce stade sont implémentées basiquement.
Ajouter la méthode createAndAddGraphicalPage dans WorkflowEditor :
private void createAndAddGraphicalPage() {
GraphicalWorkflowEditor graphicalPage = new GraphicalWorkflowEditor();
try {
int index = addPage(graphicalPage, getEditorInput());
setPageText(index, "Graphics");
} catch (PartInitException e) {
e.printStackTrace();
}
}
Appeler la méthode createAndAddGraphicalPage dans la méthode WorkflowEditor#createPages() (juste avant la construction de la page source) :
public class WorkflowEditor ...
@Override
public void createPages() {
...
// Add graphical page
createAndAddGraphicalPage();
// Add source page
createAndAddSourcePage();
...
}
...
private void createAndAddGraphicalPage() {
GraphicalWorkflowEditor graphicalPage = new GraphicalWorkflowEditor();
try {
int index = addPage(graphicalPage, getEditorInput());
setPageText(index, "Graphics");
} catch (PartInitException e) {
e.printStackTrace();
}
}
...
Relancez le plugin et vous aurrez l'erreur suivante :

Le ligne de code 236 de la classe GraphicalEditor qui pose problème est la suivante :
protected CommandStack getCommandStack() {
return getEditDomain().getCommandStack();
}
protected DefaultEditDomain getEditDomain() {
return editDomain;
}
Comme on peut le voir, le problème vient du fait que le champs editDomain est null (pour plus d'information sur EditDomain voir section GEF - EditDomain). Il faut donc l'initialiser à travers notre classe GraphicalWorkflowEditor . Pour cela ajouter le constructeur de GraphicalWorkflowEditor comme suit :
public GraphicalWorkflowEditor() {
super.setEditDomain(new DefaultEditDomain(this));
}
Ce qui donne :
package org.example.workflow.presentation.graphical;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
public class GraphicalWorkflowEditor extends GraphicalEditorWithFlyoutPalette {
public GraphicalWorkflowEditor() {
super.setEditDomain(new DefaultEditDomain(this));
}
@Override
protected PaletteRoot getPaletteRoot() {
return null;
}
@Override
public void doSave(IProgressMonitor monitor) {
}
}
Relancez le plugin et vous aurrez une page GEF vide avec la palette :

Nous avons vu qu'il est impératif de définir L'org.eclipse.gef.EditDomain de GEF à la classe de base GEF GraphicalEditor. Mais a quoi sert cette instance? L'EditDomain de GEF permet de collecter l'état d'un éditeur GEF :
ATTENTION!!! Il ne faut pas confondre stack de commandes GEF org.eclipse.gef.commands.CommandStack qui est une classe, avec stack de commandes EMF org.eclipse.emf.common.command.CommandStack qui est une interface. Elles ont le même rôle mais n'utilisent pas les mêmes structures.
Une stack de commandes GEF org.eclipse.gef.commands.CommandStack contient des commandes GEF de type org.eclipse.gef.commands.Command. CommandStack#execute(org.eclipse.gef.commands.Command command) permet d'executer une commande GEF. Dans le cas d'un outil de création de figures, cet outil créé une commande GEF de création de figure et l'ajoute à la stack de commande GEF via la méthode execute. La stack de commande GEF permet ainsi de gérer le undo/redo (comme EMF.Edit).
Comme nous l'avons vu précédemment, la classe de base de GEF pour un éditeur graphique est GraphicalEditor. GEF fournit 2 autres implementations GraphicalEditorWithPalette et GraphicalEditorWithFlyoutPalette qui éténdent GraphicalEditor. En d'autres termes pour créer un éditeur graphique on peut étendre :
org.eclipse.gef.ui.parts.GraphicalEditor :

L'utilisation de cette classe permet d'avoir une zone graphique uniquement.
org.eclipse.gef.ui.parts.GraphicalEditorWithPalette :

L'utilisation de cette classe permet par défaut d'avoir une zone graphique à droite de l'éditeur et une palette d'outils (outil de sélection, de création de figures...) à gauche de la l'éditeur.
org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette :

L'utilisation de cette classe permet d'avoir par défaut une zone graphique à droite de l'éditeur et une palette d'outils à droite de la l'éditeur. La palette peut être cachée en cliquant sur le petit triangle à coté du libéllé Palette.
Vous devez être identifié pour poster un commentaire.
| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 |
Copyright © 2000-2012 - www.developpez.com