Home » Modeling » GMF (Graphical Modeling Framework) » An easier way to create diagram elements?
An easier way to create diagram elements? [message #498438] |
Mon, 16 November 2009 17:30  |
Eclipse User |
|
|
|
I'm trying to programmatically create diagram elements based on data in a file.
An element can have a name (label), and sub elements, each of which may have it's own name.
Based on what I've seen in the tutorials, to do this I'm making a request and command for each element I want to add, and executing the command to actually create the model element and the corresponding view. Then to create the sub-elements, I get the results of the previous execution (DiagramCommandStack.getReturnValues), and create more requests and commands, etc., etc. Then I make more requests and commands in order to set the label values of each element.
It works, but it's very laborious. What I really want is to create the model elements and set their values directly, something like:
Model myNewModel = new Model();
ModelElement elem = new ModelElement();
elem.setName("A");
SubElement subElem = new SubElement();
subElem.setName("B");
elem.addChild(subElem);
myNewModel.add(elem);
.. and then have GMF take this model and render it, since GMF 'knows' all the mappings between model elements and their editparts, etc.
I know that the underlying model in GMF is represented by a ResourceSet in an EditingDomain, but is there a way to set the values directly and have GMF 'do the hard work'...?
I hope what I'm asking is clear.
Any suggestions welcome... thanks!
|
|
|
Re: An easier way to create diagram elements? [message #498442 is a reply to message #498438] |
Mon, 16 November 2009 17:48   |
Eclipse User |
|
|
|
Hi,
Model myNewModel = new Model();
ModelElement elem = new ModelElement();
elem.setName("A");
SubElement subElem = new SubElement();
subElem.setName("B");
elem.addChild(subElem);
myNewModel.add(elem);
This might actually work.
So here is what I did. I needed to "refactor" my diagram. I assosiate some edit parts with a collection of other edit parts and their connections.
So I had to delete all edit parts and create one edit part and connections. plus i had to create a new diagram and "paste" the deleted connections and editparts in there.
For creating a new diagram, I just looked at the new diagram wizard which gave me enough hints. I think this might not work for you though, since u are not creating a completely new file, right?
But replacing the deleted editparts in the old one with a new diagram and creating connections did work with less commands I think.
I had to create a seperate deleteCommand for every graphicaleditpart I had to delete.
To create the newone however, I just used the Factory method and created one XXXImpl object. There I set all the other atributes.
I created connectionImpl object that I simply added to the other impl. I set the label and the other properties and then I was able to create one CreateViewCommand that created the new editpart and all its incoming and outgoing connections on the diagram.
I also had to create a SetCommand to set the new Editparts on the parentEditPart.
So I think you can simply create your impl object and add every underling object to that. As long as it is underlying, GMF should create everything for you. As soon as you have to create more then one object to the diagram, you have to create more commands.
I hope that helps you. I know my way of explaining things is not too good, so if something is not clear feel free to ask and i will try my best to make it clearer 
Best regards,
Artur
|
|
| |
Re: An easier way to create diagram elements? [message #498583 is a reply to message #498535] |
Tue, 17 November 2009 10:14   |
Eclipse User |
|
|
|
Hi Indigo,
I think that GMF let's you modify figures without writing transaction as long as the element you are modifying is not under "GMF control", so the editing domain of the editor you want to add it, doesn't know about it which is why the objects can be mopdified.
For each element that is going to be created on the diagram and has no other connection to the diagram then it's parent canvas you will need a CreateViewCommand (later). to finally add the created objects to the model of the parent element itself you will need a command too. I used a set command, however I don't know if that was the smartest one.
I think if an element that has child elements contained by the parent element you don't need to create Commands to add them (like for me the connection edit parts that were contained by the element I added to the canvas).
This is how you would create a CreateViewCommand with an existing element:
private Command createViewCommand(EObject template) {
CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(new EObjectAdapter(
template), Node.class, ((IHintedType) XXXElementTypes
.getElementType(XXXEditPart.VISUAL_ID)).getSemanticHint(), true, CanvasEditPart
.getDiagramPreferencesHint());
viewDescriptor.setPersisted(true);
CreateViewRequest createViewRequest = new CreateViewRequest(viewDescriptor);
Command createViewCommand = CanvasEditPart.getCommand(createViewRequest);
return createViewCommand;
}
The canvas still has to return the command and the neccessary request has a subclass for the viewdescriptor which pretty much defines what view is gonna be created. The template EObject would be the XXXImpl that you created with your factory and modified before. Make sure to use the EObjectAdapter since the ViewDescriptor does not accept EObject without adapters I think.
The XXXEditPart is the type of EditPart you want to create.
The SetCommand is a lot easier I think. You have to execute that one after the CreateViewCommand because at that point the canvas doesn't know about the newly created View. I think there is a way to pack that into the same command but I couldn't figure out how to do that and still create a modified view and not just a plain one:
The SetCommand takes a SetRequest that requests the changing of a EAtribute of your canvas EObject. You can look up the API for the specifics.
Hope that helps.
Best,
Artur
Indigo wrote on Tue, 17 November 2009 06:45 | Arthur,
Thank you very much for the response and the good advice. I don't understand everything you've said, not because it's badly explained, but because of my lack of knowledge of GMF/EMF .
So to use "the Factory method and created one XXXImpl object", I can do something like:
Element newElement = FactoryImpl.eINSTANCE.createElement();
newElement.setName("A");
But the next part: "then I was able to create one CreateViewCommand that created the new editpart and all its incoming and outgoing connections on the diagram."
Can you provide some more detail on how you did that?
Thanks again.
|
|
|
| |
Re: An easier way to create diagram elements? [message #498760 is a reply to message #498655] |
Wed, 18 November 2009 10:02   |
Eclipse User |
|
|
|
Hi,
This seems to be right to me. But remember the SetCommand will actually set a new value. So I assume the model_Elements of your
canvas is a list. If you set the newElementImpl this might not work. You most likely would have to set the old list plus the new element.
newValue = new ArrayList(oldList)
newValue.add(newImpl)
setCommand (.... , newValue)
That way all the old elements will be still on the canvas and the new one will too.
I assume thought that there is some kind of an addCommand that would just add the new element. Would be a lot nicer.
best,
artur
Indigo wrote on Tue, 17 November 2009 17:05 | Hi Artur,
many thanks for that detailed response. I'm trying it now. For the second part, 'Set' ing the new view onto the canvas, I think it should look something like this, do you agree?
SetRequest reqSet = new SetRequest(
canvasEditPart.getEditingDomain(),
(EObject)canvasEditPart.getModel(),
MyPackage.eINSTANCE.getModel_Elements(),
newElementImpl);
SetValueCommand cmd= new SetValueCommand(reqSet);
canvasEditPart.getDiagramEditDomain().getDiagramCommandStack ().execute(new ICommandProxy(cmd));
Thanks.
|
|
|
| | | |
Re: An easier way to create diagram elements? [message #505401 is a reply to message #505393] |
Wed, 30 December 2009 07:02   |
Eclipse User |
|
|
|
Cicviki,
well, I'm a newbie too, so I'm not sure how much I can help, but I can tell you what I did.
I created a menu item that appears in the GMF-generated editor (look in the tutorial part 3, under ''Custom Actions", here http://wiki.eclipse.org/GMF_Tutorial_Part_3). When the menu item is selected it executes code that reads in my file and parses the contents to figure out what to create. Then I used the command/request framework (see "Creating New Elements And Corresponding Views", here http://wiki.eclipse.org/GMF_Tips) to create elements based on what's in the file. This works, but I plan to change it to try to create the items using the approach described earlier in this post - building my model elements first and then having GMF create them, which should be cleaner.
The whole process of creating diagram elements is a bit confusing and complicated, see also the post entitled "To create nodes and links from code: it' possible to have a final answer about it?".
Hope this helps.
|
|
| |
Re: An easier way to create diagram elements? [message #548427 is a reply to message #498583] |
Wed, 21 July 2010 15:04  |
Eclipse User |
|
|
|
Artur Kronenberg wrote on Tue, 17 November 2009 10:14 | Hi Indigo,
I think that GMF let's you modify figures without writing transaction as long as the element you are modifying is not under "GMF control", so the editing domain of the editor you want to add it, doesn't know about it which is why the objects can be mopdified.
For each element that is going to be created on the diagram and has no other connection to the diagram then it's parent canvas you will need a CreateViewCommand (later). to finally add the created objects to the model of the parent element itself you will need a command too. I used a set command, however I don't know if that was the smartest one.
I think if an element that has child elements contained by the parent element you don't need to create Commands to add them (like for me the connection edit parts that were contained by the element I added to the canvas).
This is how you would create a CreateViewCommand with an existing element:
private Command createViewCommand(EObject template) {
CreateViewRequest.ViewDescriptor viewDescriptor = new CreateViewRequest.ViewDescriptor(new EObjectAdapter(
template), Node.class, ((IHintedType) XXXElementTypes
.getElementType(XXXEditPart.VISUAL_ID)).getSemanticHint(), true, CanvasEditPart
.getDiagramPreferencesHint());
viewDescriptor.setPersisted(true);
CreateViewRequest createViewRequest = new CreateViewRequest(viewDescriptor);
Command createViewCommand = CanvasEditPart.getCommand(createViewRequest);
return createViewCommand;
}
The canvas still has to return the command and the neccessary request has a subclass for the viewdescriptor which pretty much defines what view is gonna be created. The template EObject would be the XXXImpl that you created with your factory and modified before. Make sure to use the EObjectAdapter since the ViewDescriptor does not accept EObject without adapters I think.
The XXXEditPart is the type of EditPart you want to create.
The SetCommand is a lot easier I think. You have to execute that one after the CreateViewCommand because at that point the canvas doesn't know about the newly created View. I think there is a way to pack that into the same command but I couldn't figure out how to do that and still create a modified view and not just a plain one:
The SetCommand takes a SetRequest that requests the changing of a EAtribute of your canvas EObject. You can look up the API for the specifics.
Hope that helps.
Best,
Artur
|
This works fine for me, I can create nodes now. My problem is, when I save my diagram and close my application. The new created node does not appear the next time I start my application. How to persist the node in the file? Thx
[Updated on: Wed, 21 July 2010 15:05] by Moderator
|
|
|
Goto Forum:
Current Time: Mon Jul 07 12:59:39 EDT 2025
Powered by FUDForum. Page generated in 0.05623 seconds
|