我已经实施了GEF编辑器用于图状EMF模型,具有去除命令为图中的一个特定类型的节点。 我想我已经做是为了使这个设置工作(一切必要的步骤vainolo的博客一直是一个很大的帮助)。
然而,当我删除模型元素, 认为没有得到刷新 ,即图中的模型元素不是从编辑器视图中删除了,我不知道为什么。 我会非常感激,如果有人可以看看我的消息来源并指出我的任何问题(以及可能的解决方案:))。 提前谢谢了!
下面是什么,我觉得是这个问题的重要课程。 请不要让我知道我应该添加更多的代码/编辑代码,等等。(我已经离开了,我认为没有帮助的代码,例如,getter和setter方法,类变量)。 谢谢!
的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());
}
}
编辑
再execc的评论:是的, refreshChildren()
被调用。 我已经通过重写它,并添加一个简单的测试此System.err
线,这是正在对一个节点的缺失在控制台上显示:
@Override
public void refreshChildren() {
super.refreshChildren();
System.err.println("refreshChildren() IS being called!");
}
编辑2
有趣的(嗯......)的事情是,当我关闭编辑器并坚持模型,然后重新打开相同的文件,该节点不再画,并没有出现在模型中。 但是,这是什么意思? 上午我工作的一个陈旧的模式吗? 或刷新/获取不正常的模特儿?
编辑3
我刚刚发现了一个奇怪的事情,这或许可以解释我有的所有主题? 在getModelChildren()
方法调用我allModelObjects.addAll(((Diagram) getModel()).getMyNodes());
和getMyNodes()
返回一个不可修改 EList
。 我发现,当我试图做的线沿线的东西((Diagram) getModel()).getMyNodes().remove(getMyNode())
在删除命令,它抛出一个UnsupportedOperationException
...嗯。
编辑4
呃, 有人杀我好吗 ? 我仔细检查我是否处理相同Diagram
对象在任何时候,虽然这样做我遇到一个很尴尬的事情绊倒:
该getModelChildren()
的方法DiagramEditPart
中的最后一个版本阅读约。 像这样:
@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;
}
我想偷了大家的时间道歉! 您的建议是非常有益的,也确实帮助了我,终于追查错误!
我也学到了一些经验教训,在他们之中:始终粘贴在原代码,过度simplifaction可以掩饰你的错误! 我已经学到了很多关于EMF, Adapter
,和全球环境基金。 仍然: