GEF + EMF:为什么在调用refreshChildren()时,我的编辑器删除已删除对象的图? [英] GEF + EMF: Why doesn't my editor remove the Figure for a removed object when refreshChildren() is called?

查看:407
本文介绍了GEF + EMF:为什么在调用refreshChildren()时,我的编辑器删除已删除对象的图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为类似图形的EMF模型实现了一个GEF编辑器,对图中某种类型的节点使用了一个remove命令。我想我已经完成了所有必要的步骤,以使此设置工作( vainolo blog 已经是一个很大的帮助)。



但是,当我删除模型元素时,视图不会刷新,即模型元素的图形不会从编辑器视图中删除,我不知道为什么。我非常感谢,如果有人可以看看我的来源,并指向我的任何问题(和可能的解决方案:))。非常感谢!



下面是我认为这个问题的重要类。请让我知道,如果我添加进一步的代码/编辑代码等(我遗漏了我认为没有帮助的代码,例如getters和setters,类变量)。非常感谢!



DiagramEditPart



 







$ b)
adapter = new DiagramAdapter();
}

@Override protected IFigure createFigure(){
Figure figure = new FreeformLayer();
return figure;
}

@Override protected void createEditPolicies(){
installEditPolicy(EditPolicy.LAYOUT_ROLE,new DiagramXYLayoutPolicy());
}

@Override protected List< EObject> getModelChildren(){
List< EObject> allModelObjects = new ArrayList< EObject>();
if((Diagram)getModel())。getMyNodes()!= null)
allModelObjects.addAll((Diagram)getModel())。getMyNodes()
return allModelObjects;
}

@Override public void activate(){
if(!isActive()){
(Diagram)getModel())eAdapters添加(适配器);
}
super.activate();
}


@Override public void deactivate(){
if(isActive()){
(Diagram)getModel ().remove(adapter);
}
super.deactivate();
}

public class DiagramAdapter implements Adapter {

@Override public void notifyChanged(Notification notification){
switch(notification.getEventType()){
case Notification.REMOVE:refreshChildren();
break;
默认值:
break;
}
}

@Override public Notifier getTarget(){
return(Diagram)getModel();
}

@Override public void setTarget(Notifier newTarget){
//不执行任何操作。
}

@Override public boolean isAdapterForType(Object type){
return type.equals(Diagram.class);
}

}

}

MyNodeEditPart

  public class MyNodeEditPart extends AbstractGraphicalEditPart {

public MyNodeEditPart(MyNode model){
this.setModel(model);
adapter = new MyNodeAdapter();
}

@Override protected IFigure createFigure(){
return New MyNodeFigure();
}

@Override protected void createEditPolicies(){
installEditPolicy(EditPolicy.COMPONENT_ROLE,new MyNodeComponentEditPolicy());
}

@Override protected void refreshVisuals(){
MyNodeFigure figure =(MyNodeFigure)getFigure();
DiagramEditPart parent =(DiagramEditPart)getParent();
Dimension labelSize = figure.getLabel()。getPreferredSize();
Rectangle layout = new Rectangle((getParent()。getChildren()。indexOf(this)* 50),
(getParent()。getChildren()。indexOf(this)* 50) .width + 20),
(labelSize.height + 20));
parent.setLayoutConstraint(this,figure,layout);
}

public List< Edge> getModelSourceConnections(){
if((MyNode)getModel()!= null&((MyNode)getModel())getDiagram()!= null){
ArrayList& sourceConnections = new ArrayList< Edge>();
for(Edge edge:((MyNode)getModel())getDiagram()。getOutEdges((MyNode)getModel())。getId())){
sourceConnections.add(edge);
}
return sourceConnections;
}
return null;
}

// +目标连接的相同方法

@Override public void activate(){
if(!isActive()){
((MyNode)getModel())。eAdapters()。add(adapter);
}
super.activate();
}

@Override public void deactivate(){
if(isActive()){
((MyNode)getModel())eAdapters (适配器);
}
super.deactivate();
}

public class MyNodeAdapter实现Adapter {

@Override
public void notifyChanged(Notification notification){
refreshVisuals();
}

@Override
public Notifier getTarget(){
return(MyNode)getModel();
}

@Override
public void setTarget(Notifier newTarget){
// Do nothing
}

@覆盖
public boolean isAdapterForType(Object type){
return type.equals(MyNode.class);
}

}

}

MyNodeComponentEditPolicy




@Override
protected命令createDeleteCommand(GroupRequest deleteRequest){
DeleteMyNodeCommand nodeDeleteCommand = new DeleteMyNodeCommand((MyNode)getHost()。getModel());
return nodeDeleteCommand;
}

}

DeleteMyNodeCommand

  public class DeleteMyNodeCommand extends Command {

public DeleteMyNodeCommand model){
this.node = model;
this.graph = node.getDiagram();
}

@Override public void execute(){
getMyNode()。setDiagram(null);
System.out.println(模型是否仍然存在于图形中?+ getGraph()。getMyNodes()。contains(getMyNode()));
//返回false,即图形在此时不包含模型对象!
}

@Override public void undo(){
getMyNode()。setDiagram(getGraph());
}

}





$ b b

EDIT



重新执行execc的注释:Yes, refreshChildren()正在呼叫。我通过覆盖它并添加一个简单的 System.err 行,在控制台上显示删除一个节点:

$ b $测试这个b

  @Override 
public void refreshChildren(){
super.refreshChildren
System.err.println(refreshChildren()IS is called!);
}






EDIT 2



有趣(好...)的事情是,当我关闭编辑器和持久化模型,然后重新打开同一个文件,节点不再被绘,不存在于模型中。但这是什么意思?我在一个陈旧的模型上工作吗?或者正在刷新/让模型儿童无法正常工作?






编辑3



我刚刚发现了一个奇怪的事情,这可能 解释我有什么?在 getModelChildren()方法中我调用 allModelObjects.addAll((Diagram)getModel())getMyNodes()); getMyNodes()返回不可修改 EList 。我发现当我尝试在删除命令中执行((Diagram)getModel())。getMyNodes()。remove(getMyNode())并且它抛出了 UnsupportedOperationException ... Hm。






4



Er,有人杀了我请
我已经仔细检查过,我是否一直处理相同的对象,而这样做时,我偶然遇到一个非常 embarassing : c $>

getModelChildren $ c>在最后的版本读约。像这样:

  @Override protected List< EObject> getModelChildren(){
List< EObject> allModelObjects = new ArrayList< EObject>();
EList< MyNode> nodes =((Diagram)getModel())。getMyNodes();
for(MyNode node:nodes){
if(node.getDiagram()!= null); // ### D'Uh! ###
allModelObjects.add(node);
}
return allModelObjects;
}

我想为窃取每个人的时间而道歉!



我还学到了一些课程,其中包括:始终粘贴原始代码,过度简化可能掩盖你的错误!我学到了很多关于EMF, Adapter 和GEF。仍然:



>

解决方案

在代码的下面部分的第5行中有一个分号太多,即在if语句之后: if(node.getDiagram()!= null);

  1 @Override protected List< EObject> getModelChildren(){
2 List< EObject> allModelObjects = new ArrayList< EObject>();
3 EList< MyNode> nodes =((Diagram)getModel())。getMyNodes();
4 for(MyNode node:nodes){
5 if(node.getDiagram()!= null);
6 allModelObjects.add(node);
7}
8 return allModelObjects;
9}


I have implemented a GEF editor for a graph-like EMF model, with a remove command for a certain type of node in the graph. I think I've done all the necessary steps in order to make this set up work (vainolo's blog has been a great help).

However, when I'm deleting a model element, the view doesn't get refreshed, i.e., the figure for the model element isn't removed from the editor view, and I have no idea why. I'd be extremely grateful if somebody could have a look at my sources and point me to any problems (and possibly solutions :)). Many thanks in advance!

Below are what I think are the important classes for this issue. Please do let me know should I add further code/edit the code, etc. (I've left out code that I thought doesn't help, e.g., getters and setters, class variables). Thanks!

DiagramEditPart

public class DiagramEditPart extends AbstractGraphicalEditPart {

    public DiagramEditPart(Diagram model) {
        this.setModel(model);
        adapter = new DiagramAdapter();
    }

    @Override protected IFigure createFigure() {
        Figure figure = new FreeformLayer();
        return figure;
      }

      @Override protected void createEditPolicies() {
        installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramXYLayoutPolicy());
      }

      @Override protected List<EObject> getModelChildren() {
          List<EObject> allModelObjects = new ArrayList<EObject>();
          if (((Diagram) getModel()).getMyNodes() != null)
          allModelObjects.addAll(((Diagram) getModel()).getMyNodes());
          return allModelObjects;
      }

      @Override public void activate() {
          if(!isActive()) {
              ((Diagram) getModel()).eAdapters().add(adapter);
          }
          super.activate();
      }


      @Override public void deactivate() {
          if(isActive()) {
              ((Diagram) getModel()).eAdapters().remove(adapter);
          }
          super.deactivate();
      }

    public class DiagramAdapter implements Adapter {

          @Override public void notifyChanged(Notification notification) {
              switch (notification.getEventType()) {
            case Notification.REMOVE: refreshChildren();
                break;
            default:
                break;
            }
          }

          @Override public Notifier getTarget() {
              return (Diagram) getModel();
          }

          @Override public void setTarget(Notifier newTarget) {
              // Do nothing.
          }

          @Override public boolean isAdapterForType(Object type) {
              return type.equals(Diagram.class);
          } 

      }

}

MyNodeEditPart

public class MyNodeEditPart extends AbstractGraphicalEditPart {

    public MyNodeEditPart(MyNode model) {
         this.setModel(model);
         adapter = new MyNodeAdapter();
    }

    @Override protected IFigure createFigure() {
        return new MyNodeFigure();
    }

    @Override protected void createEditPolicies() {
        installEditPolicy(EditPolicy.COMPONENT_ROLE, new MyNodeComponentEditPolicy());
    }

    @Override protected void refreshVisuals() {
        MyNodeFigure figure = (MyNodeFigure) getFigure();
        DiagramEditPart parent = (DiagramEditPart) getParent();
        Dimension labelSize = figure.getLabel().getPreferredSize();
        Rectangle layout = new Rectangle((getParent().getChildren().indexOf(this) * 50), 
                (getParent().getChildren().indexOf(this) * 50), (labelSize.width + 20), 
                (labelSize.height + 20));
        parent.setLayoutConstraint(this, figure, layout);
    }

    public List<Edge> getModelSourceConnections() {
        if ((MyNode) getModel() != null && ((MyNode) getModel()).getDiagram() != null) {
            ArrayList<Edge> sourceConnections = new ArrayList<Edge>();
            for (Edge edge : ((MyNode) getModel()).getDiagram().getOutEdges(((MyNode) getModel()).getId())) {
                sourceConnections.add(edge);
            }
            return sourceConnections;
        }
        return null;
    }

    // + the same method for targetconnections

    @Override public void activate() {
        if (!isActive()) {
            ((MyNode) getModel()).eAdapters().add(adapter);
        }
        super.activate();
    }

    @Override public void deactivate() {
        if (isActive()) {
            ((MyNode) getModel()).eAdapters().remove(adapter);
        }
        super.deactivate();
    }

    public class MyNodeAdapter implements Adapter {

        @Override
        public void notifyChanged(Notification notification) {
            refreshVisuals();
        }

        @Override
        public Notifier getTarget() {
            return (MyNode) getModel();
        }

        @Override
        public void setTarget(Notifier newTarget) {
            // Do nothing
        }

        @Override
        public boolean isAdapterForType(Object type) {
            return type.equals(MyNode.class);
        }

    }

}

MyNodeComponentEditPolicy

public class MyNodeComponentEditPolicy extends ComponentEditPolicy {

    @Override
    protected Command createDeleteCommand(GroupRequest deleteRequest) {
        DeleteMyNodeCommand nodeDeleteCommand = new DeleteMyNodeCommand((MyNode) getHost().getModel());
        return nodeDeleteCommand;
    }

}

DeleteMyNodeCommand

public class DeleteMyNodeCommand extends Command {

    public DeleteMyNodeCommand(MyNode model) {
        this.node = model;
        this.graph = node.getDiagram();
    }

    @Override public void execute() {
        getMyNode().setDiagram(null);
        System.out.println("Is the model still present in the graph? " + getGraph().getMyNodes().contains(getMyNode())); 
            // Returns false, i.e., graph doesn't contain model object at this point!
    }

    @Override public void undo() {
        getMyNode().setDiagram(getGraph());
    }

}


EDIT

Re execc's comment: Yes, refreshChildren() is being called. I've tested this by overriding it and adding a simple System.err line, which is being displayed on the console on deletion of a node:

@Override
public void refreshChildren() {
    super.refreshChildren();
    System.err.println("refreshChildren() IS being called!");
}


EDIT 2

The funny (well...) thing is, when I close the editor and persist the model, then re-open the same file, the node isn't painted anymore, and is not present in the model. But what does this mean? Am I working on a stale model? Or is refreshing/getting the model children not working properly?


EDIT 3

I've just found a peculiar thing, which might explain the isues I have? In the getModelChildren() method I call allModelObjects.addAll(((Diagram) getModel()).getMyNodes());, and getMyNodes() returns an unmodifiable EList. I found out when I tried to do something along the lines of ((Diagram) getModel()).getMyNodes().remove(getMyNode()) in the delete command, and it threw an UnsupportedOperationException... Hm.


EDIT 4

Er, somebody kill me please? I've double-checked whether I'm handling the same Diagram object at all times, and while doing this I stumbled across a very embarassing thing:

The getModelChildren() method in DiagramEditPart in the last version read approx. like this:

@Override protected List<EObject> getModelChildren() {
    List<EObject> allModelObjects = new ArrayList<EObject>();
    EList<MyNode> nodes = ((Diagram) getModel()).getMyNodes();
    for (MyNode node : nodes) {
        if (node.getDiagram() != null); // ### D'Uh! ###
            allModelObjects.add(node);
    }
    return allModelObjects;
 }

I'd like to apologize for stealing everyone's time! Your suggestions were very helpful, and indeed helped my to finally track down the bug!

I've also learned a number of lessons, amongst them: Always paste the original code, over-simplifaction may cloak your bugs! And I've learned a lot about EMF, Adapter, and GEF. Still:

解决方案

There is one semi-colon too many in line 5 of the following part of the code, namely after the if statement: if (node.getDiagram() != null);:

1   @Override protected List<EObject> getModelChildren() {
2       List<EObject> allModelObjects = new ArrayList<EObject>();
3       EList<MyNode> nodes = ((Diagram) getModel()).getMyNodes();
4       for (MyNode node : nodes) {
5           if (node.getDiagram() != null); 
6               allModelObjects.add(node);
7       }
8       return allModelObjects;
9    }

这篇关于GEF + EMF:为什么在调用refreshChildren()时,我的编辑器删除已删除对象的图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆