How to replace or remove the diagram's root object [message #1785864] |
Sat, 21 April 2018 00:22 |
David G. Messages: 10 Registered: April 2015 Location: Madrid, Spain |
Junior Member |
|
|
I'm trying to replace the diagram's root object (the eObject associated with my diagram, it contains every other eObject).
I have a feature where I create multiple clones of my root object (Graph class) and do some calculations on them. Then I can choose one of the clones and I want to replace it in my diagram.
I've been trying to do this, but the contained objects seem to be left behind, and I'm getting errors on save due to unreferenced elements (I guess I'm removing the root element, but not the child elements):
public static void setRootGraph(Diagram diagram, Graph graph) {
PictogramLink link = diagram.getLink();
if (link == null) {
// Create the pictogram link object
link = PictogramsFactory.eINSTANCE.createPictogramLink();
}
EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(diagram);
Command command;
// Remove the Graph from the diagram resource
command = new RemoveCommand(editingDomain, diagram.eResource().getContents(), link.getBusinessObjects());
editingDomain.getCommandStack().execute(command);
// Add the Graph to the diagram resource
link.getBusinessObjects().clear();
link.getBusinessObjects().add(graph);
command = new AddCommand(editingDomain, diagram.eResource().getContents(), graph);
editingDomain.getCommandStack().execute(command);
// Set the pictogram link object for the diagram object
command = new SetCommand(editingDomain, diagram,
PictogramsPackage.eINSTANCE.getDiagram().getEStructuralFeature(PictogramsPackage.DIAGRAM__LINK), link);
editingDomain.getCommandStack().execute(command);
}
Any tip on how to accomplish this?
Thanks!
|
|
|
|
Re: How to replace or remove the diagram's root object [message #1785993 is a reply to message #1785922] |
Mon, 23 April 2018 23:34 |
David G. Messages: 10 Registered: April 2015 Location: Madrid, Spain |
Junior Member |
|
|
Thanks for the feedback!
I've gone back and tried doing it in a custom feature, but the result is simmilar...
This is the execute method of the custom feature:
@Override
public void execute(ICustomContext context) {
hasDoneChanges = true;
// Access the graph
Graph theGraph = GraphUtil.getRootGraph(getDiagram());
// Add every node from the new graph
theGraph.getNodes().clear();
theGraph.getNodes().addAll(newGraph.getNodes());
// Add every edge from the new graph
theGraph.getEdges().clear();
theGraph.getEdges().addAll(newGraph.getEdges());
// Model is modified now, with new or different edges
updateAllEdges();
updateGraph(theGraph);
}
The feature runs ok, but when I try to save the diagram I get this:
Quote:
org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The object 'graphdom.impl.EdgeImpl@360a3106 (marked: false, guid: null, weight: 0)' is not contained in a resource.
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:301)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:265)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:389)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:1430)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.saveOnlyIfChangedWithMemoryBuffer(ResourceImpl.java:1144)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.save(ResourceImpl.java:985)
at org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior$1$1.run(DefaultPersistencyBehavior.java:342)
at org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl.runExclusive(TransactionalEditingDomainImpl.java:328)
at org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior$1.run(DefaultPersistencyBehavior.java:353)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2240)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2262)
at org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior.save(DefaultPersistencyBehavior.java:360)
at org.eclipse.graphiti.ui.editor.DefaultPersistencyBehavior$SaveOperation.run(DefaultPersistencyBehavior.java:470)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:119)
Caused by: org.eclipse.emf.ecore.xmi.DanglingHREFException: The object 'graphdom.impl.EdgeImpl@360a3106 (marked: false, guid: null, weight: 0)' is not contained in a resource.
at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.handleDanglingHREF(XMLHelperImpl.java:754)
at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.getURIFragment(XMLHelperImpl.java:725)
at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.getIDREF(XMLHelperImpl.java:747)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveIDRefMany(XMLSaveImpl.java:2023)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1370)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveFeatures(XMLSaveImpl.java:1224)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.saveElementID(XMLSaveImpl.java:2716)
It seems like the previous Edges are not really being removed from the model when I clear the list of their containing EObject...
As I write this, I tried again wtih EcoreUtil.deleteAll and it seemed to work, but now I realize that, even if the EObject gets updated, the diagram doesn't seem to notice, as the graphical representations are not affected...
Is there some quick way in Graphiti, to remove each EObject from these lists and their associated pictogram elements? Maybe instead of dealing with EObjects I should be trying to call delete and add features for each of the objects? :-m
[Updated on: Mon, 23 April 2018 23:35] Report message to a moderator
|
|
|
|
Re: How to replace or remove the diagram's root object [message #1786207 is a reply to message #1786068] |
Thu, 26 April 2018 22:47 |
David G. Messages: 10 Registered: April 2015 Location: Madrid, Spain |
Junior Member |
|
|
Thanks for your guidance! :-)
Finally I got it through: First iterating over the domain objects in the collections and invoking the delete feature and then iterating over the new objects and triggering the add feature.
The most tricky parts were:
* Instantiating the DeleteContext, as I had to 'traverse' from the domain object to the pictogram element to instantiate it with the constructor (it needs the PE, can't work with the object). Also I had to 'tune' the MultiDeleteInfo to prevent multiple Yes/No popups.
* Instantiating the AddContext (and AddConnectionContext, which are different), as I had to programmatically set the target container or the objects would be 'lost' without a parent.
Also, I had to 'clone' the domain objects (really I EcoreUtil.clone'd the whole parent object) before adding them to the 'active' one, as when I added them to the active object they would get removed from the other one (preventing me from switching them back and forth). I guess this has to do with my model and EMF enforcing that the objects have a single parent, but was unknown for me (I'm an EMF newbie after all :-))
A few snippets, should it be handy for someone:
The delete part (inside a loop in my code):
Node node = theGraph.getNodes().get(i);
PictogramElement pictogramElement = Graphiti.getLinkService().getPictogramElements(diagram, node)
.get(0);
DeleteContext delContext = new DeleteContext(pictogramElement);
delContext.setMultiDeleteInfo(new MultiDeleteInfo(false, false, 0));
getFeatureProvider().getDeleteFeature(delContext).execute(delContext);
The add part (in a loop as well):
Node node = newGraph.getNodes().get(i);
theGraph.getNodes().add(node);
AddContext addContext = new AddContext();
addContext.setNewObject(node);
addContext.setLocation(node.getXCoord(), node.getYCoord());
addContext.setTargetContainer(diagram);
getFeatureProvider().getAddFeature(addContext).add(addContext);
|
|
|
Powered by
FUDForum. Page generated in 0.03601 seconds