如何通过适配器从EMF模型及其GEF编辑器中删除模型对象

时间:2012-06-23 09:05:39

标签: model controller adapter eclipse-emf eclipse-gef

这个问题主要是我question about EMF listening mechanisms的后续行动。

所以,我有一个基于通用图模型的第三方EMF模型(不可编辑)。结构如下:

   Project
      |
  ItemGraph
      |
    Item
      |
   Document
      |
  DocumentGraph
 /       |     \
Tokens Nodes   Relations(Edges)

我有一个适用于DocumentGraph的GEF编辑器(即根对象,也许这是一个问题?):getGraphicalViewer().setContents(documentGraph)。编辑器具有以下编辑部分结构:

   DocumentGraphEP
     /        \
Primary      Connection
 LayerEP     LayerEP
  /     \        |
TokenEP NodeEP RelationEP

PrimaryLayerEPConnectionLayerEP都有简单的String s作为模型,它们未在EMF(域)模型中表示。它们只是用于向编辑器添加主要(即节点)层和连接层(带ShortestPathConnectionRouter)。

问题:我正在尝试使用EMF适配器的工作方式,并尝试使用可用的教程,主要是EMF-GEF Eclipse tutorialvainolo's blog,和vogella's tutorial。我以为我会从一个简单的事情开始,所以试图从图表中删除一个节点,看看我是否让它工作。我没有,我也没有看到问题所在。

我可以选择一个节点,并在工具栏中使用通用删除Action,但是当我点击它时,没有任何反应。以下是不同负责部分的相应源代码。请非常友好地指出我能找到的任何错误(思考,编码错误,无论什么)。

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();
  }
}

所有似乎才能正常工作:在编辑器中选择节点后,工具栏中会激活删除符号,但单击它时,编辑器中没有任何操作。

我非常感谢任何指示:)。

修改

好吧,我想模型对象的删除应该由DocumentGraphEditPart(父级)而不是对象本身来处理。所以我修改了前者以实现Adapter,但直到没有任何反应。

DocumentGraphEP的notifyChanged方法

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;
        }
    }

所以也许整个事件毕竟是图层的非模型编辑部分的问题?

1 个答案:

答案 0 :(得分:2)

确实存在EditPart不代表任何现有模型元素的问题。一旦我编辑了EditPart的结构,它就可以正常工作。