How to add EClass objects programmatically to a diagram? [message #900541] |
Tue, 07 August 2012 12:58 |
andrej dyck Messages: 14 Registered: May 2012 |
Junior Member |
|
|
Hello,
for about a week, I am trying to create "new" elements on a GMF diagram without success. Now you are my hope to finally get it done.
This is what I have as "requirements": Modelling with "Eclipse Modelling Tools" one creates a EMF Project and then Ecore Model (.ecore) and an Ecore Diagram (.ecorediag). Opening the .ecorediag file in the default editor (EcoreDiagramEditor) containing a GMFResource. No I want my plug-in to add (and remove) objects to this diagram and its underlying model. Concrete, I want to be able to add EClass, EDataType, EEnum, EOperation, EAttribute, EReference, Inheritance objects, i.e., more or less the default Objects and Connections from the "Palette". Further, I already get, e.g., EClass, objects. These objects are created programmatically and should be added to the diagram.
This is what I have found so far:
First approach: So I found this CreateViewAndElementRequest and looked up where it is used and how. The following code snippet works partially for a new EClass object:
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecoretools.diagram.part.EcoreDiagramEditor;
import org.eclipse.emf.ecoretools.diagram.providers.EcoreElementTypes;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.diagram.core.edithelpers.CreateElementRequestAdapter;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.notation.Node;
IWorkbenchPart activePart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
EcoreDiagramEditor diagramEditor = (EcoreDiagramEditor) activePart;
DiagramEditPart diagramEditPart = diagramEditor.getDiagramEditPart();
EClass myCreatedClass = ...;
CreateElementRequest createElementRequest = new CreateElementRequest(EcoreElementTypes.EClass_1001);
createElementRequest.setNewElement(myCreatedClass);
CreateElementRequestAdapter createElementRequestAdapter = new
CreateElementRequestAdapter(createElementRequest);
CreateViewAndElementRequest.ViewAndElementDescriptor veDescriptor = new
CreateViewAndElementRequest.ViewAndElementDescriptor(
createElementRequestAdapter, Node.class,
((IHintedType) EcoreElementTypes.EClass_1001).getSemanticHint(),
diagramEditPart.getDiagramPreferencesHint());
CreateViewAndElementRequest veRequest = new
CreateViewAndElementRequest(veDescriptor);
Command command = diagramEditPart.getCommand(veRequest);
command.execute();
This command execution creates a new EClass object with the name "EClass0" in both the .ecore and .ecorediag file and views the element in the diagram. Yay! But it completely ignores myCreatedClass. And I do not have a clue how (1) I get the newly created element so I can modify it or (2) how to make this command clear, that I really want my EClass object to be inserted.
Second approach: The next thing I have found is the DropObjectsRequest. But all I get is an Exception while executing the corresponding command and I cannot find examples how to use it right. This is how I have tried this:
DropObjectsRequest dropObjectsRequest = new DropObjectsRequest();
dropObjectsRequest.setObjects(Collections.singletonList(myCreatedClass));
Command command = diagramEditPart.getCommand(dropObjectsRequest);
command.execute();
But maybe it is a wrong approach anyway.
Third approach: Since I can create, remove and edit EObjects with org.eclipse.emf.common.command.* in a Resource, another idea of mine was to update the model of the diagram [((Diagram) diagramEditor.getEditingDomain().getResourceSet().getResources().get(0).getContents().get(0)).getElement()] and then "reinitialize" the diagram. I have found InitializeAndLayoutDiagramCommand which use EcoreDiagramContentInitializer to initialize diagram content. Well since it is generated code, I cannot overwrite functionality But this one way would be cool and easy for me. I already tried to use this command without the use of LayoutService and it (partially) worked. But obviously it had duplicated all existing elements since it gets all elements from the model resource and puts them into the diagram resource. Is there another (similar) class I can use to update the diagram from the model?
Regards,
Andrej
|
|
|
|
Re: How to add EClass objects programmatically to a diagram? [message #900732 is a reply to message #900689] |
Wed, 08 August 2012 10:44 |
andrej dyck Messages: 14 Registered: May 2012 |
Junior Member |
|
|
Hello Ralph,
thank you for the reply! With the CreateUnspecifiedTypeRequest the code shrinks a lot. And I figured that I can get the newly created objects with the getNewObject() method. If I am right, I should then be able to alter these objects. Do I create relationships, e.g., inheritance, the same way?
Now, trying to alter the objects. Coming back with an update. For everyone else, here is my previous code using CreateUnspecifiedTypeRequest.
CreateUnspecifiedTypeRequest request = new
CreateUnspecifiedTypeRequest(
Collections.singletonList(EcoreElementTypes.EClass_1001),
diagramEditPart.getDiagramPreferencesHint());
Command command = diagramEditPart.getCommand(request);
command.execute();
Object newObject = request.getNewObject(); // these are the newly created objects
Regards,
Andrej
|
|
|
|
|
|
|
Re: How to add EClass objects programmatically to a diagram? [message #900800 is a reply to message #900793] |
Wed, 08 August 2012 14:11 |
andrej dyck Messages: 14 Registered: May 2012 |
Junior Member |
|
|
Hi,
OK. I just tried DropObjectsRequest and it worked for me. Here is the quick & dirty code for those who are interested:
EClass myCreatedClass = ...
EPackage package = ((Diagram) editingDomain.getResourceSet().getResources().get(0).getContents().get(0)).getElement();
editingDomain.getCommandStack().execute(AddCommand.create(editingDomain, package, null, myCreatedClass);
DropObjectsRequest dropObjectsRequest = new DropObjectsRequest();
dropObjectsRequest.setObjects(Collections.singletonList(myCreatedClass));
dropObjectsRequest.setLocation(new Point(15, 15));
diagramEditor.getDiagramEditDomain().getDiagramCommandStack().execute(diagramEditPart.getCommand(dropObjectsRequest));
Of course, now I have to figure out how to "show up" references and delete stuff. For those who are interested in arranging the elements, there is an ArrangeRequest which I have not tried yet, so I cannot give you any code snippet.
Cheers,
Andrej
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05774 seconds