質問

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 :).

EDIT

Okay, I guess the removal of a model object should be handled by the DocumentGraphEditPart (the parent) rather than the object itself. So I have modified the former to implement Adapter as well, but till nothing happens.

DocumentGraphEP's notifyChanged method

public void notifyChanged(Notification notification) {
        System.out.println("I'm in the graph EP");// DELETE_SYSO
        int type = notification.getEventType();
        switch( type ) {
            case Notification.ADD:
            case Notification.ADD_MANY:
            case Notification.REMOVE:
                System.out.println("I'm in graph remove");// DELETE_SYSO
                refreshChildren();
                ((PrimaryLayerEditPart)getChildren().get(0)).refresh();
                ((PrimaryLayerEditPart)getChildren().get(0)).refreshVisuals();
                refreshVisuals();
                break;
            case Notification.REMOVE_MANY:
                refreshChildren();
                break;
            case Notification.SET:
                refreshVisuals();
                break;
        }
    }

So perhaps the whole affair is an issue with the non-model edit parts for the layers after all?

役に立ちましたか?

解決

This is indeed a problem of having EditParts that do not represent any existing model element. Once I had edites the structure of the EditParts, it worked fine.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top