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 :
Schooljfb.examples.gmf.schoolpackage 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 fileDashboard view : Domain Gen Model file (school.genmodel)Domain Model file (school.ecore)school.genmodel fileGenerate Model CodeGenerate Edit CodeGenerate Editor Codederive label on the left of the Tooling Def Model rectangle of the Dashboard viewschool.gmftool as file name and click NextDiagram class as Diagram Element and click NextNode 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 viewschool.gmfgraph as file name and click NextDiagram class as Diagram Element and click NextNode column, only the following entries must be checked : Classroom, School, StudentLinks column, only the friends : Student entry must be checkedLabel column, only the following entries must be checked : Classroom.name, School.name, Student.nameschool.gmfgraph filePolyline Decoration StudentFriendsTargetDecoration nodeRectangle ClassroomFigure node :Flow Layout nodeBoder Layout nodeRectangle node and set its name to ClassroomCompartmentFigureLabel ClassroomNameFigure, add a Border Layout Data node and set its properties :Alignment=BEGINNINGVertical=trueRectangle ClassroomCompartmentFigure, add a Border Layout Data node and set its properties :Alignment=CENTERVertical=trueFigure 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 SchoolCompartmentFigureLabel SchoolNameFigure, add a Border Layout Data node and set its properties :Alignment=BEGINNINGVertical=trueRectangle SchoolCompartmentFigure, add a Border Layout Data node and set its properties :Alignment=CENTERVertical=trueFigure 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 getFigureSchoolCompartmentFigureFigure=Figure Descriptor SchoolFigureName=SchoolClassroomsCompartmentCompartment node and set its properties to :Accessor=Child Access getFigureClassroomCompartmentFigureFigure=Figure Descriptor ClassroomFigureName=ClassroomStudentsCompartmentschool.gmfgraph file (but as Text file (right click on the file, menu Open with > Text Editorxsi: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 viewschool.gmfmap as file name and click NextDiagram class as Diagram Element and click NextSelect Diagram Palette wizard page, just click nextSelect Diagram Canvas wizard page, just click nextMapping wizard page, remove the Classroom entry from Links zoneFinishschool.gmfmap file generated aboveMapping node add a Link Mapping node and set its properties :Target Feature=Student.friends:StudentDiagram Link=Connection StudentFriendConnectionTool=Creation Tool FriendNode 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:ClassroomCompartment 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=ClassroomDiagram Node=Node Classroom (ClassroomFigure)Tool=Creation Tool ClassroomNode Mapping <Classroom/Classroom> node : Featured Label Mapping and set its properties to :Feature to display=Classroom.name:EStringDiagram Label=Diagram Label ClassroomNameChild Reference node and set its Containment Feature property to Classroom.students:StudentCompartment 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=StudentDiagram Node=Node Student (StudentFigure)Tool=Creation Tool StudentNode Mapping <Student/Student> node, add a Featured Label Mapping and set its properties to :Feature to display=Student.name:EStringDiagram Label=Diagram Label StudentNametransform label above the Diagram Editor Gen model rectangle of the Dashboard viewschool.gmfgen fileGen Compartment SchoolSchoolClassroomsCompartmentEditPart node and set the List Layout property to trueGen Compartment ClassroomClassroomStudentsCompartmentEditPart node and set the List Layout property to falseGenerate 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 layoutof theRectanglefigure 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 :
private static Bigraphe createInitialModel() { Bigraphe bigraphe = BigrapheFactory.eINSTANCE.createBigraphe(); Region reg = BigrapheFactory.eINSTANCE.createRegion(); Noeud noeud = BigrapheFactory.eINSTANCE.createNoeud(); noeud.setNom("N1"); reg.setNom("Reg1"); bigraphe.setNom("Bigraphe"); reg.getContenirNoeud().add(noeud); bigraphe.getContenirRegions().add(reg); return bigraphe; }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 NOTCelle-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”>
<school name="Sample"> <classrooms name="Class Room"> <students name="Student1" friends="//@school/@classrooms.1/@students.0"/> </classrooms> <classrooms name="Classroom 2"> <students name="Student2"/> </classrooms> </school></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”>
<classrooms name="Class Room"> <students name="Student1" friends="//@school/@classrooms.1/@students.0"/> </classrooms> <classrooms name="Classroom 2"> <students name="Student2"/> </classrooms> </school>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?