With GMF, node compartments traditionnaly have list layouts or not layout at all.
The second choice is selected when on want to put the diagram nodes freely in the compartment. The first choice allows to get nodes automatically positionned vertically in the parent node. It is then not possible to move or resize these nodes. For example, we may use this feature if we want to built an UML class diagram editor ; in a class node, two compartments should be inserted vertically, the first accepting attributes, the second accepting operations.
In this tutorial, we will see how to get an horizontal layout which may sometimes fit better one's needs.
The diagram editor will accept one school. In this school, we will be able to add classrooms. Every classroom may accept students. And finally, we will allow students to have friends !
Full code is availabale through :
This tutorial has been built with :
School
jfb.examples.gmf.school
package jfb.examples.gmf.school.model; /** * @model */ public interface Diagram { /** * @model containment="true" */ School getSchool(); }
package jfb.examples.gmf.school.model; import java.util.List; /** * @model */ public interface School { /** * @model */ String getName(); /** * @model containment="true" */ List<Classroom> getClassrooms(); }
package jfb.examples.gmf.school.model; import java.util.List; /** * @model */ public interface Classroom { /** * @model */ String getName(); /** * @model containment="true" */ List<Student> getStudents(); }
package jfb.examples.gmf.school.model; /** * @model */ public interface Student { /** * @model */ String getName(); /** * @model */ List<Student> getFriends(); }
EMF Generator Model
named school.genmodel
in the model
folder (right click on the School
project, select New
, choose EMF Generator Model
)school.ecore
file that has been generated above and by selecting Initialize ecore_diagram diagram file
Dashboard view
: Domain Gen Model
file (school.genmodel
)Domain Model
file (school.ecore
)school.genmodel
fileGenerate Model Code
Generate Edit Code
Generate Editor Code
derive
label on the left of the Tooling Def Model
rectangle of the Dashboard view
school.gmftool
as file name and click Next
Diagram
class as Diagram Element
and click Next
Node
column, only the following entries must be checked : Classroom
, Student
(School
is not checked because, later in this tutorial, we will make it automatically available when a new diagram is initiated).Links
column, only the friends : Student
entry must be checkedderive
label on the left of the Graphical Def Model
rectangle of the Dashboard view
school.gmfgraph
as file name and click Next
Diagram
class as Diagram Element
and click Next
Node
column, only the following entries must be checked : Classroom
, School
, Student
Links
column, only the friends : Student
entry must be checkedLabel
column, only the following entries must be checked : Classroom.name
, School.name
, Student.name
school.gmfgraph
filePolyline Decoration StudentFriendsTargetDecoration
nodeRectangle ClassroomFigure
node :Flow Layout
nodeBoder Layout
nodeRectangle
node and set its name to ClassroomCompartmentFigure
Label ClassroomNameFigure
, add a Border Layout Data
node and set its properties :Alignment
=BEGINNING
Vertical
=true
Rectangle ClassroomCompartmentFigure
, add a Border Layout Data
node and set its properties :Alignment
=CENTER
Vertical
=true
Figure Descriptor ClassroomFigure
node, add a Child Access
and in the property view, select the Rectangle ClassroomCompartmentFigure
entry.Rectangle SchoolFigure
node :Flow Layout
nodeBoder Layout
nodeRectangle
node and set its name to SchoolCompartmentFigure
Label SchoolNameFigure
, add a Border Layout Data
node and set its properties :Alignment
=BEGINNING
Vertical
=true
Rectangle SchoolCompartmentFigure
, add a Border Layout Data
node and set its properties :Alignment
=CENTER
Vertical
=true
Figure Descriptor SchoolFigure
node, add a Child Access
and in the property view, select the Rectangle SchoolCompartmentFigure
entry.Canvas
node :Compartment
node and set its properties to :Accessor
=Child Access getFigureSchoolCompartmentFigure
Figure
=Figure Descriptor SchoolFigure
Name
=SchoolClassroomsCompartment
Compartment
node and set its properties to :Accessor
=Child Access getFigureClassroomCompartmentFigure
Figure
=Figure Descriptor ClassroomFigure
Name
=ClassroomStudentsCompartment
school.gmfgraph
file (but as Text file (right click on the file, menu Open with > Text Editor
xsi:type
attribute of the actualFigure
node of the ClassroomFigure
and set it to gmfgraph:RoundedRectangle
:<actualFigure xsi:type="gmfgraph:RoundedRectangle" name="ClassroomFigure">
combine
label on the left of the Mapping Model
rectangle of the Dashboard view
school.gmfmap
as file name and click Next
Diagram
class as Diagram Element
and click Next
Select Diagram Palette
wizard page, just click nextSelect Diagram Canvas
wizard page, just click nextMapping
wizard page, remove the Classroom
entry from Links
zoneFinish
school.gmfmap
file generated aboveMapping
node add a Link Mapping
node and set its properties :Target Feature
=Student.friends:Student
Diagram Link
=Connection StudentFriendConnection
Tool
=Creation Tool Friend
Node Mapping <School/School>
node and unset its Tool
property (later in this tutorial, we will make school automatically available when a new diagram is initiated, a creation tool would be unusefull).Node Mapping <School/School>
node :Child Reference
node and set its Containment Feature
property to School.classrooms:Classroom
Compartment Mapping
node and set its properties : Children
=Child Reference <classrooms>
Compartment
=Compartment SchoolClassroomsCompartment (SchoolFigure)
Child Reference <classrooms>
node, add a Node Mapping
node and set its properties : Element
=Classroom
Diagram Node
=Node Classroom (ClassroomFigure)
Tool
=Creation Tool Classroom
Node Mapping <Classroom/Classroom>
node : Featured Label Mapping
and set its properties to :Feature to display
=Classroom.name:EString
Diagram Label
=Diagram Label ClassroomName
Child Reference
node and set its Containment Feature
property to Classroom.students:Student
Compartment Mapping
node and set its properties : Children
=Child Reference <students>
Compartment
=Compartment ClassroomStudentsCompartment (ClassroomFigure)
Child Reference <students>
node, add a Node Mapping
node and set its properties : Element
=Student
Diagram Node
=Node Student (StudentFigure)
Tool
=Creation Tool Student
Node Mapping <Student/Student>
node, add a Featured Label Mapping
and set its properties to :Feature to display
=Student.name:EString
Diagram Label
=Diagram Label StudentName
transform
label above the Diagram Editor Gen model
rectangle of the Dashboard view
school.gmfgen
fileGen Compartment SchoolSchoolClassroomsCompartmentEditPart
node and set the List Layout
property to true
Gen Compartment ClassroomClassroomStudentsCompartmentEditPart
node and set the List Layout
property to false
Generate diagram editor
label in the Diagram Editor Gen model
rectangle of the Dashboard view
At this point, if we launch the diagram editor, we will not be able to create classrooms and students because we have chosen not to add a creation button for the School
element.
The following steps will allow to automatically add a new school every time a diagram is created :
jfb.examples.gmf.school.diagram.part.SchoolDiagramEditorUtil
java classcreateInitialModel
method like this (do not forget to add NOT
after @generated
):/** * Create a new instance of domain element associated with canvas. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated NOT */ private static Diagram createInitialModel() { Diagram diagram = SchoolFactory.eINSTANCE.createDiagram(); School school = SchoolFactory.eINSTANCE.createSchool(); diagram.setSchool(school); return diagram; }
As we have no creation tool for our school, we want to prevent it from being removed. To do that :
jfb.examples.gmf.school.diagram.edit.helpers.SchoolEditHelper
java classgetDestroyElementCommand
method like this (do not forget to add NOT
after @generated
) ; this will disable the Delete from model
popup menu item :/** * @generated NOT */ protected ICommand getDestroyElementCommand(DestroyElementRequest req) { // Prevents from removing the figure return UnexecutableCommand.INSTANCE; }
jfb.examples.gmf.school.diagram.edit.parts.SchoolEditPart
java classcreateDefaultEditPolicies
method like this (do not forget to add NOT
after @generated
) ; this will disable the delete action when you type on the delete key :/** * @generated NOT */ protected void createDefaultEditPolicies() { installEditPolicy(EditPolicyRoles.CREATION_ROLE, new CreationEditPolicy()); super.createDefaultEditPolicies(); installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new SchoolItemSemanticEditPolicy()); installEditPolicy(EditPolicy.LAYOUT_ROLE, createLayoutEditPolicy()); installEditPolicy(EditPolicy.COMPONENT_ROLE, new ComponentEditPolicy() { public Command getCommand(Request request) { // If the user presses the delete key, don't delete if (request instanceof GroupRequestViaKeyboard && RequestConstants.REQ_DELETE.equals(request.getType())) { return UnexecutableCommand.INSTANCE; } return super.getCommand(request); } }); }
Now we will modify the School
layout behavior in order to get vertical classrooms :
jfb.examples.gmf.school.diagram.edit.parts.SchoolSchoolClassroomsCompartmentEditPart
java classcreateFigure
method like this (do not forget to add NOT
after @generated
):/** * @generated NOT */ public IFigure createFigure() { ResizableCompartmentFigure result = (ResizableCompartmentFigure) super .createFigure(); result.setTitleVisibility(false); // Fix the margins Insets insets = result.getContentPane().getInsets(); insets.top = 5; insets.bottom = 5; insets.left = 5; insets.right = 5; // Layout behavior modification : data must be represented horizontally ConstrainedToolbarLayout layoutMgr = (ConstrainedToolbarLayout) result .getContentPane().getLayoutManager(); layoutMgr.setVertical(false); layoutMgr.setStretchMajorAxis(true); // uses all the avalaible space layoutMgr.setStretchMinorAxis(true); // uses all the avalaible space layoutMgr.setSpacing(5); return result; }
We will also make the default school size bigger than 40×40 :
jfb.examples.gmf.school.diagram.edit.parts.SchoolEditPart
java classcreateNodePlate
method like this (do not forget to add NOT
after @generated
):/** * @generated NOT */ protected NodeFigure createNodePlate() { DefaultSizeNodeFigure result = new DefaultSizeNodeFigure(600, 300); return result; }
This will allow to use rectilinears edges by default :
jfb.examples.gmf.school.diagram.preferences.DiagramConnectionsPreferencePage
java class/** * @generated NOT */ public static void initDefaults(IPreferenceStore preferenceStore) { preferenceStore.setDefault(IPreferenceConstants.PREF_LINE_STYLE, Routing.RECTILINEAR); }
At this point, our diagram has a default : if you click on a classroom, and click again on the classroom's compartment, the compartment is marked as selected. Iy you right click on it, you can select Delete from model
. If you select it, the compartment is deleted from the diagram, but after it is not possible to get it back and the contained students are not deleted from the model !
To diable this, we have to :
jfb.examples.gmf.school.diagram.edit.policies.ClassroomClassroomStudentsCompartmentItemSemanticEditPolicy
java class/** * @generated NOT */ protected Command getSemanticCommand(IEditCommandRequest request) { if (request instanceof DestroyRequest) { return null; } return super.getSemanticCommand(request); }
I hope that this material will be helpful for you. If you want to support it, your help is welcome :
Discussion
Hi, Thank u for this tutoriel. But i want, if u don't mind to ask a question. In my project, i need to add 2 labels in the same line in a compartment. Is it possible and how to do it? Thank u in advance. Asma
Hello,
I think it is possible. If I had to do that, in the EMF I would create 2 objects, the first (the parent object) containing the second (the child object, don't forget to set the containment property to true). In the second object, I would add my two attributes corresponding to the 2 labels that you want to put on the same line. I don't describe the way to get the compartment work as it is already described in the tutorials of this site. In the gmfgraph file, I would remove the
Flow layout
of theRectangle
figure that corresponds to the child object, I would put a BorderLayout instead and I would a Border Layout Data to each label, the first with the alignment set toBEGINNING
, and the second toEND
….Hope it helps (if it understandable !….)
Regards,
JFB
Hi, Thank you very much for those tutoriels wich are really super helpfull. I am working in a GMF project and i am still beginner, i am searching for a book wich describes the generated Java classes of the plugin. I need also to personnalise the properties view of the generated modeler. Finally i need to add compartment as label and not rectangle ( i tried it but i didnt work :( ) Thank you very much
Hi,
I cannot give you any advice on a gook book about GMF. I personnaly found the answers to my problems on the net or by myself after a few hours of hard job !!!! It is true that the documentation available on this technology is not very accessible (that is why I decided to publish these tutorials).
As far as I can see, the personlization the properties view of your modeler is an EMF issue. This is not specific GMF.
I don't exactly understand what you mean when you say that you want to add a compartment as a label. Could you precise it ?
Regards,
JFB
Hi thank you very much for this tutorial. It helped me a lot. once again thankyou. But my problem is am unable to move student diagrams inside classroom. could you please tell me what should i do for this.
Hi
Did you try to drag'n'drop the students ? It it suppose to work that way….
Regards,
JFB
Hello,
First of all thanks loads for this tutorial!!! But I just have a small question: I want to create a new node in the diagram every time I create a shortcut. Do you have any idea how to do this??
Hi, Could you precise what you mean by shortcut ? Regards, JFB
You know when you drag and drop a node from the navigator to the diagram? It like creates a shortcut to that node. Or if you right click the diagram and select create shortcut from the context menu?
http://www.jevon.org/wiki/GMF_Drag_Drop <this shows what the shortcuts are exactly.
Oh I'm sorry but I have not experimented the GMF shortcut feature… If you get a solution to your problem, please let me know, I should add a tutorial on this subject. Thank you.
Hey Jean, I'm interested in “Diagram initialization” well, i'm gonna show you what i did exactly :
But when i run the Diagram my elements are stored in the Domain Model but they aren't shown in the diagram. any ideas?
Bonjour,
Quelque chose me dit que vous parlez Français. Du bon vieux franglais dans le code, normalement je ne dois pas me tromper ! Ce que vous faites me paraît convenable. Peut-être avez-vous changé la signature de la méthode générée par GMF ? Celle-ci retournait bien initialement un 'Bigraphe' ?
Une question subsidiaire : les références permettant de naviguer de l'objet Bigraphe à l'objet Noeud en passant par l'objet Region sont elles bien de type
Containment
?JF
Bonjour, Merci de m'avoir repondu ^^
avez-vous changé la signature de la méthode générée par GMF ?
@generated NOT
Celle-ci retournait bien initialement un 'Bigraphe' ?
Une question subsidiaire : les références permettant de naviguer de l'objet Bigraphe à l'objet Noeud en passant par l'objet Region sont elles bien de type Containment ?
voilà une capture d'écran pour le fichier Domain Model du diagramme http://i55.tinypic.com/2qki70m.jpg
Bonsoir,
Ma dernière question portait plus sur le modèle ecore que vous avez produit mais la capture d'écran fournie répond à ma question. La hiérarchie des noeuds montrent que nous avons bien des références de type containment. Dans ces cas là je ne vois pas vu de l'extérieur d'erreur dans les éléments apporté. Je repartirais de zéro à votre place pour regénérer un éditeur de diagramme GMF pour re-vérifier que vous n'avez pas fait d'erreur dans les différentes étapes.
JFB
Merci pour votre aide! une autre question, j'ai cette error “Top level node 'Containment Feature' must be available in the diagram 'Domain Element' or its super-class”. comment puis-je régler ce problème?
Merci d'avance.
Les Top Node Reference ne peuvent être associées qu'à des éléments (features) de type containement de l'élément de base sur lequel s'appuie votre diagramme (je crois qu'il s'agit du Bigraphe dans votre cas). Les autres éléments doivent être déclarés sous forme de Child Reference ensuite.
Vous pouvez jeter un oeil à cet exemple : http://gmfsamples.tuxfamily.org/wiki/lib/exe/fetch.php?cache=&media=gmf-tuto5-gmfmap.png tiré du tutorial 5.
JFB
Merci Jean, mais j'ai des noeuds imbriqués es-que ça pose un problème?
voilà mon Mapping Model : http://i53.tinypic.com/oh4nxs.png
Bonjour Mr.Jean, merci beaucoup pour votre aide, mon problème est résolu, merci encore une fois
juste une petite remarque, j'utilise OSATE (Environnement de manipulation des descriptions AADL)
Je ne connais pas ce produit. Est-ce une surcouche de GMF ?
OSATE est un environnement de manipulation des descriptions AADL qui utilise EMF pour définir “AADL Meta Model” et utilise GMF pour générer “Graphic AADL Editor”. et voilà un exemple : http://i53.tinypic.com/dx1dza.jpg
Hi,
I just want to submit a quick notice. In the Tooling definition, you wrote: “School is not checked because, later in this tutorial, we will make it automatically available when a new diagram is initiated”
But in the screenshot shown, you included School in the checkbox. Please correct it!
Thank you very much for this useful tutorial.
Hi !
You are perfectly right !!!! This is corrected.
Best regards,
JFB
Hello,
Thanks a lot for the great tutorial.
I have one question. I am creating a model with similar compartment with horizontal layout. However I want to be able to drag-n-drop a child (e.g. classroom) out of the parent compartment (e.g school) and put it somewhere else in the diagram (maybe in another compartment). Do you have any idea how can I do that?
Thanks, Lily
Nice tutorial!! Worth spending time. I have a question. In the above example, why can't we create ContraintToolBarLayout instead of BorderLayout while creating gmfgraph? Why do we need to modify code?
Hi ,
Very Nice tutorial for beginner. the default.school shows as below
<?xml version=“1.0” encoding=“UTF-8”?> <jfb.examples.gmf.school:Diagram xmi:version=“2.0” xmlns:xmi=“http://www.omg.org/XMI” xmlns:jfb.examples.gmf.school=“http:///jfb/examples/gmf/school.ecore”>
</jfb.examples.gmf.school:Diagram>
If I dont want root tag i.e is <jfb.examples.gmf.school:Diagram >. what changes should I do so that my default.school looks as follows:
<school name=“Sample”>
Regards, Pramod
Bonjour,
J'ai vu que vous parliez français, donc je vais poser ma question en français.
Est-ce que c'est possible de faire la même chose sans pour autant avoir un noeud “Root” dans le modèle ecore (ici “Diagram”), parce que ça embrouille le fichier XML en sortie.
Bien à vous.
JR
I tried to do all steps described in this tutorial on Eclipse Luna 4.4.1. I got many errors in the generated School.diagramm
1)Many exceptions were in the dialog, which was open during generation, all of them like Exception (Boolean expected (was: org.eclipse.ocl.ecore.internal.OCLStandardLibraryImpl$1)!:in CodeStyle, line 18) while generating code Boolean expected (was: org.eclipse.ocl.ecore.internal.OCLStandardLibraryImpl$1)!:in CodeStyle, line 18
2)Generated plugin was without manifest file and also without dependencies. I manually added dependencies
3) The last type of problems were because not all code was generated, some classes referenced to another which wasn't generated at all: jfb.examples.gmf.school.model.diagram.edit.policies.ClassroomClassroomStudentsCompartmentCanonicalEditPolicy; jfb.examples.gmf.school.model.diagram.part.SchoolVisualIDRegistry; jfb.examples.gmf.school.model.diagram.providers.SchoolElementTypes; jfb.examples.gmf.school.model.diagram.edit.policies.ClassroomItemSemanticEditPolicy; jfb.examples.gmf.school.model.diagram.part.SchoolVisualIDRegistry;
and so on.
I tried to do other GMF tutorials and result was the same. Could be possible that GMF doesn't work with eclipse luna?