How to remove a model object from an EMF model and its GEF Editor via Adapter
- by s.d
This question is principally a follow-up to my question about EMF listening mechanisms.
So, I have a third-party EMF model (uneditable) which is based on a generic graph model. The structure is as follows:
Project
|
ItemGraph
|
Item
|
Document
|
DocumentGraph
/ | \
Tokens Nodes Relations(Edges)
I have a GEF editor which works on the DocumentGraph (i.e., not the root object, perhaps this is a problem?): getGraphicalViewer().setContents(documentGraph). THe editor has the following edit part structure:
DocumentGraphEP
/ \
Primary Connection
LayerEP LayerEP
/ \ |
TokenEP NodeEP RelationEP
PrimaryLayerEP and ConnectionLayerEP both have simple Strings as model, which are not represented in the EMF (domain) model. They are simply used to add a primary (i.e., node) layer, and a connection layer (with ShortestPathConnectionRouter) to the editor.
Problem: I am trying to get myself into the workings of EMF adapters, and have tried to make use of the available tutorials, mainly the EMF-GEF Eclipse tutorial, vainolo's blog, and vogella's tutorial. I thought I'd start with an easy thing, so tried to remove a node from the graph and see if I get it to work. Which I didn't, and I don't see where the problem is.
I can select a node, and have the generic delete Action in my toolbar, but when I click it, nothing happens. Here is the respective source code for the different responsible parts. Please be so kind to point me to any errors (of thinking, coding errors, whathaveyou) you can find.
NodeEditPart
public class NodeEditPart extends AbstractGraphicalEditPart implements Adapter {
protected IFigure createFigure() {
return new NodeFigure();
}
protected void createEditPolicies() {
....
installEditPolicy(EditPolicy.COMPONENT_ROLE, new NodeComponentEditPolicy());
}
protected void refreshVisuals() {
NodeFigure figure = (NodeFigure) getFigure();
SNode model = (SNode) getModel();
PrimaryLayerEditPart parent = (PrimaryLayerEditPart) getParent();
// Set text
figure.getLabel().setText(model.getSName());
....
}
public void activate() {
if (isActive()) return;
// start listening for changes in the model
((Notifier)getModel()).eAdapters().add(this);
super.activate();
}
public void deactivate() {
if (!isActive()) return;
// stop listening for changes in the model
((Notifier)getModel()).eAdapters().remove(this);
super.deactivate();
}
private Notifier getSDocumentGraph() {
return ((SNode)getModel()).getSDocumentGraph();
}
@Override
public void notifyChanged(Notification notification) {
int type = notification.getEventType();
switch( type ) {
case Notification.ADD:
case Notification.ADD_MANY:
case Notification.REMOVE:
case Notification.REMOVE_MANY:
refreshChildren();
break;
case Notification.SET:
refreshVisuals();
break;
}
}
@Override
public Notifier getTarget() {
return target;
}
@Override
public void setTarget(Notifier newTarget) {
this.target = newTarget;
}
@Override
public boolean isAdapterForType(Object type) {
return type.equals(getModel().getClass());
}
}
NodeComponentEditPolicy
public class NodeComponentEditPolicy extends ComponentEditPolicy {
public NodeComponentEditPolicy() {
super();
}
protected Command createDeleteCommand(GroupRequest deleteRequest) {
DeleteNodeCommand cmd = new DeleteNodeCommand();
cmd.setSNode((SNode) getHost().getModel());
return cmd;
}
}
DeleteNodeCommand
public class DeleteNodeCommand extends Command {
private SNode node;
private SDocumentGraph graph;
@Override
public void execute() {
node.setSDocumentGraph(null);
}
@Override
public void undo() {
node.setSDocumentGraph(graph);
}
public void setSNode(SNode node) {
this.node = node;
this.graph = node.getSDocumentGraph();
}
}
All seems to work fine: When a node is selected in the editor, the delete symbol is activated in the toolbar, but when it is clicked, nothing happens in the editor.
I'd be very thankful for any pointers :).