On crée un nouveau package qu'on va appeler "tutogef.model".
On va ensuite écrire une class (dans ce package) qui servira de class mère pour tous les éléments de notre modèle. cette class contient les propriétés élémentaire qui serviront a toutes les class hérité.
package tutogef.model;

import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.geometry.Rectangle;

public class Node {

        private String name;
        private Rectangle layout;
        private List<Node> children;
        private Node parent;
       
        public Node(){
                this.name = "Unknown";
                this.layout = new Rectangle(10, 10, 100, 100);
                this.children = new ArrayList<Node>();
                this.parent = null;
        }
       
        public void setName(String name) {
                this.name = name;
        }
       
        public String getName() {
                return this.name;
        }
       
        public void setLayout(Rectangle layout) {
                this.layout = layout;
        }
       
        public Rectangle getLayout() {
                return this.layout;
        }
       
        public boolean addChild(Node child) {
                child.setParent(this);
                return this.children.add(child);
        }
       
        public boolean removeChild(Node child) {
                return this.children.remove(child);
        }
       
        public List<Node> getChildrenArray() {
                return this.children;
        }
       
        public void setParent(Node parent) {
                this.parent = parent;
        }
       
        public Node getParent() {
                return this.parent;
        }
}


Ensuite on écrit une class qui hérite de Node et qui sera la class la plus haute de notre hiérarchie. Prenons l'exemple d'une entreprise : elle contient plusieurs services et chaque service emploie plusieurs personnes.
Voici les class Entreprise, Service, Employé.
package tutogef.model;

public class Entreprise extends Node {
        private String address;
        private int capital;
       
        public void setAddress(String address) {
                this.address = address;
        }
       
        public void setCapital(int capital) {
                this.capital = capital;
        }
       
        public String getAddress() {
                return this.address;
        }
       
        public int getCapital() {
                return this.capital;
        }
}

package tutogef.model;

public class Service extends Node {
        private int etage;
       
        public void setEtage(int etage) {
                this.etage = etage;
        }
       
        public int getEtage() {
                return this.etage;
        }
}

package tutogef.model;

public class Employe extends Node {
        private String prenom;
       
        public void setPrenom(String prenom) {
                this.prenom = prenom;
        }
       
        public String getPrenom() {
                return this.prenom;
        }
}


Chaque objet du modèle doit être associé a une figure (draw2d) et un editpart.
nous avons trois class pour le modèle, il faut donc trois class pour les figures et trois class pour les editparts... (un editpart est un objet qui va faire la liaison entre son objet du modèle et sa représentation visuelle.)

Nous allons créer la class figure et editpart associé a entreprise pour pouvoir l'afficher. (on place les class figures dans un package qu'on va appeler tutogef.figure et celles des editparts dans un package tutogef.editpart)
package tutogef.figure;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;

public class EntrepriseFigure extends Figure {
        private Label labelName = new Label();
        private Label labelAddress = new Label();
        private Label labelCapital = new Label();
        private XYLayout layout;

        public EntrepriseFigure() {
                layout = new XYLayout();
                setLayoutManager(layout);
               
                labelName.setForegroundColor(ColorConstants.blue);
                add(labelName);
                setConstraint(labelName, new Rectangle(5, 5, -1, -1));
                labelAddress.setForegroundColor(ColorConstants.lightBlue);
                add(labelAddress);
                setConstraint(labelAddress, new Rectangle(5, 17, -1, -1));
                labelCapital.setForegroundColor(ColorConstants.lightBlue);
                add(labelCapital);
                setConstraint(labelCapital, new Rectangle(5, 30, -1, -1));
               
                setForegroundColor(ColorConstants.black);
               setBorder(new LineBorder(5));   
        }
       
        public void setLayout(Rectangle rect) {
                setBounds(rect);
        }
       
        public void setName(String text) {
                labelName.setText(text);
        }
       
        public void setAddress(String text) {
                labelAddress.setText(text);
        }
       
        public void setCapital(int capital) {
                labelCapital.setText("Capital : "+capital);
        }
}

package tutogef.part;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import tutogef.figure.EntrepriseFigure;
import tutogef.model.Entreprise;
import tutogef.model.Node;


public class EntreprisePart extends AbstractGraphicalEditPart{
       
        @Override
        protected IFigure createFigure() {
                IFigure figure = new EntrepriseFigure();
                return figure;
        }

        @Override
        protected void createEditPolicies() {
                // TODO Auto-generated method stub
               
        }
       
        protected void refreshVisuals(){
                EntrepriseFigure figure = (EntrepriseFigure)getFigure();
                Entreprise model = (Entreprise)getModel();

                figure.setName(model.getName());
                figure.setAddress(model.getAddress());
                figure.setCapital(model.getCapital());
        }
       
        public List<Node> getModelChildren() {
               return new ArrayList<Node>();
        }
}


Maintenant il ne reste plus qu'a "relier" tout ca :)

Il faut créer une Factory pour gérer les editpart. Une factory est une class qui va se charger de produire des objets (les editparts) appropriés selon ce qu'on souhaite avoir quelque soit la class de l'objet. Pour le moment notre factory ressemble a ceci :
package tutogef.part;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import tutogef.model.Entreprise;

public class AppEditPartFactory implements EditPartFactory {

        @Override
        public EditPart createEditPart(EditPart context, Object model) {
                AbstractGraphicalEditPart part = null
               
                if (model instanceof Entreprise) {
                        part = new EntreprisePart();
                }
               
                part.setModel(model);
                return part;
        }
}


Dans la class MyGraphicalEditor du tutorial précedent il faut surcharger la methode configureGraphicalViewer() pour dire a notre éditeur que l'on veut utiliser notre factory. On crée aussi une méthode qui va se charger de créer notre modèle objet. Puis on fini par charger notre modèle objet dans l'éditeur avec la méthode initializeGraphicalViewer()
public class MyGraphicalEditor extends GraphicalEditor {
        public Entreprise CreateEntreprise(){
                Entreprise psyEntreprise = new Entreprise();
               
                psyEntreprise.setName("Psykokwak Entreprise");
                psyEntreprise.setAddress("Quelque part sur terre");
                psyEntreprise.setCapital(100000);
               
                return psyEntreprise;
        }
        (...)
        protected void configureGraphicalViewer() {
                 super.configureGraphicalViewer();   
                 GraphicalViewer viewer = getGraphicalViewer();
                 viewer.setEditPartFactory(new AppEditPartFactory());
        }
        (...)
        protected void initializeGraphicalViewer() {
                GraphicalViewer viewer = getGraphicalViewer();
            viewer.setContents(CreateEntreprise());     
        }
}


Voila, vous pouvez exécuter.. Vous devez obtenir ce résultat :



Ne nous arrêtons pas en si bon chemin :).
Il faut répéter l'opération précédente pour la class Service et la class Employe : Ecrire son EditPart et sa Figure.. Voici les class ServiceFigure et ServicePart. Elles ressemblent beaucoups aux class EntrepriseFigure et EntreprisePart...
package tutogef.figure;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;

public class ServiceFigure extends Figure{
       
        private Label labelName = new Label();
        private Label labelEtage = new Label();
       
        public ServiceFigure() {
                XYLayout layout = new XYLayout();
                setLayoutManager(layout);
       
                labelName.setForegroundColor(ColorConstants.darkGray);
                add(labelName, ToolbarLayout.ALIGN_CENTER);
                setConstraint(labelName, new Rectangle(5, 17, -1, -1));
               
                labelEtage.setForegroundColor(ColorConstants.black);
                add(labelEtage, ToolbarLayout.ALIGN_CENTER);
                setConstraint(labelEtage, new Rectangle(5, 5, -1, -1));
               
                /** Just for Fun :) **/
                setForegroundColor(new Color(null,
                                (new Double(Math.random() * 128)).intValue() ,
                                (new Double(Math.random() * 128)).intValue(),
                                (new Double(Math.random() * 128)).intValue()));
                setBackgroundColor(new Color(null,
                                (new Double(Math.random() * 128)).intValue() + 128 ,
                                (new Double(Math.random() * 128)).intValue() + 128 ,
                                (new Double(Math.random() * 128)).intValue() + 128 ));
               
                setBorder(new LineBorder(1));
                setOpaque(true);
        }
       
        public void setName(String text) {
                labelName.setText(text);
        }
       
        public void setEtage(int etage) {
                labelEtage.setText("Etage:"+etage);
        }
       
        public void setLayout(Rectangle rect) {
                getParent().setConstraint(this, rect);
        }
}

package tutogef.part;

import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import tutogef.figure.ServiceFigure;
import tutogef.model.Node;
import tutogef.model.Service;

public class ServicePart extends AbstractGraphicalEditPart {
       
        @Override
        protected IFigure createFigure() {
                IFigure figure = new ServiceFigure();
                return figure;
        }

        @Override
        protected void createEditPolicies() {
                // TODO Auto-generated method stub
               
        }
       
        protected void refreshVisuals(){
                ServiceFigure figure = (ServiceFigure)getFigure();
                Service model = (Service)getModel();

                figure.setName(model.getName());
                figure.setEtage(model.getEtage());
                figure.setLayout(model.getLayout());
        }

        public List<Node> getModelChildren() {
               return ((Service)getModel()).getChildrenArray();
        }
}


Notez getModelChildren() juste au dessus, il faut modifier cette méthode dans la class EntreprisePart comme celle ci.
public class EntreprisePart extends AbstractGraphicalEditPart {
        (...)
        public List<Node> getModelChildren() {
               return ((Entreprise)getModel()).getChildrenArray();
        }
}


Et on recommence pour Employe...
package tutogef.figure;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Rectangle;

public class EmployeFigure extends Figure {
       
        private Label labelName = new Label();
        private Label labelFirstName = new Label();     
       
        public EmployeFigure() {
                ToolbarLayout layout = new ToolbarLayout();
                setLayoutManager(layout);
               
                labelFirstName.setForegroundColor(ColorConstants.black);
                add(labelFirstName, ToolbarLayout.ALIGN_CENTER);
               
                labelName.setForegroundColor(ColorConstants.darkGray);
                add(labelName, ToolbarLayout.ALIGN_CENTER);
               
                setForegroundColor(ColorConstants.darkGray);
                setBackgroundColor(ColorConstants.lightGray);
               
                setBorder(new LineBorder(1));
                setOpaque(true);
        }

        public void setName(String text) {
                labelName.setText(text);
        }
       
        public void setFirstName(String text) {
                labelFirstName.setText(text);
        }
       
        public void setLayout(Rectangle rect) {
                getParent().setConstraint(this, rect);
        }
}

package tutogef.part;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import tutogef.figure.EmployeFigure;
import tutogef.model.Employe;
import tutogef.model.Node;

public class EmployePart extends AbstractGraphicalEditPart{

        @Override
        protected IFigure createFigure() {
                IFigure figure = new EmployeFigure();
                return figure;
        }

        @Override
        protected void createEditPolicies() {
                // TODO Auto-generated method stub
               
        }
       
        protected void refreshVisuals(){
                EmployeFigure figure = (EmployeFigure)getFigure();
                Employe model = (Employe)getModel();

                figure.setName(model.getName());
                figure.setFirstName(model.getPrenom());
                figure.setLayout(model.getLayout());
        }

        public List<Node> getModelChildren() {
               return new ArrayList<Node>();
        }

}

(Notez que pour cette class, getModelChildren() retourne une liste vide. C'est normal car Personne est la class la plus basse dans notre hierarchie. Elle n'a pas de fils)

Il faut maintenant modifier notre factory pour qu'elle puisse gérer nos nouveaux editparts.
public class AppEditPartFactory implements EditPartFactory {

        @Override
        public EditPart createEditPart(EditPart context, Object model) {
                AbstractGraphicalEditPart part = null
               
                if (model instanceof Entreprise) {
                        part = new EntreprisePart();
                } else if (model instanceof Service) {
                        part = new ServicePart();
                } else if (model instanceof Employe) {
                        part = new EmployePart();
                }
               
                part.setModel(model);
                return part;
        }
}


Peuplons maintenant notre entreprise de services et d'employés...
Toujours dans la méthode CreateEntreprise() de la class MyGraphicalEditor, nous allons ajouter des services et des employés. Notez qu'il faut spécifier les coordonnées de chaque éléments ainsi que leur taille. (les coordonnées sont relatif par rapport au 0.0 du parent)
        public Entreprise CreateEntreprise(){
                Entreprise psyEntreprise = new Entreprise();
               
                psyEntreprise.setName("Psykokwak Entreprise");
                psyEntreprise.setAddress("Quelque part sur terre");
                psyEntreprise.setCapital(100000);
               
                        Service comptaService = new Service();
                        comptaService.setName("Compta");
                        comptaService.setEtage(2);
                        comptaService.setLayout(new Rectangle(30, 50, 250, 150));
                       
                                Employe employeCat = new Employe();
                                employeCat.setName("Debroua");
                                employeCat.setPrenom("Cat");
                                employeCat.setLayout(new Rectangle(25, 40, 60, 40));
                                comptaService.addChild(employeCat);
                       
                                Employe employeJyce = new Employe();
                                employeJyce.setName("Psykokwak");
                                employeJyce.setPrenom("Jyce");
                                employeJyce.setLayout(new Rectangle(100, 60, 60, 40));
                                comptaService.addChild(employeJyce);
                               
                                Employe employeEva = new Employe();
                                employeEva.setName("Longoria");
                                employeEva.setPrenom("Eva");
                                employeEva.setLayout(new Rectangle(180, 90, 60, 40));
                                comptaService.addChild(employeEva);     
                       
                        psyEntreprise.addChild(comptaService);
               
                        Service rhService = new Service();
                        rhService.setName("Ressources Humaine");
                        rhService.setEtage(1);
                        rhService.setLayout(new Rectangle(220, 230, 250, 150));
                       
                                Employe employePaul = new Employe();
                                employePaul.setName("Dupond");
                                employePaul.setPrenom("Paul");
                                employePaul.setLayout(new Rectangle(40, 70, 60, 40));
                                rhService.addChild(employePaul);
                               
                                Employe employeEric = new Employe();
                                employeEric.setName("Durand");
                                employeEric.setPrenom("Eric");
                                employeEric.setLayout(new Rectangle(170, 100, 60, 40));
                                rhService.addChild(employeEric);
               
                psyEntreprise.addChild(rhService);
               
                return psyEntreprise;
        }


Et voila....
Vous pouvez maintenant lancer le programme. Vous devriez obtenir ceci (Les couleurs changent a chaque fois):


Vous pouvez télécharger le projet de ce tutorial ICI.

La suite au prochain Tuto :)