`
liugang594
  • 浏览: 979763 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

GEF理解系列五(1)

    博客分类:
  • GEF
 
阅读更多
到目前为止,我们已经有了一些模型和一些调色析工具箱了。
但是我们的工具箱还不能真正的创建出新的模型来。这一节我们就要实现创建模型操作。

一、新建模型结点

首先我们看一下创建结点模型操作。以我们HelloWorldModel为例。每个HelloWorldModel只有加到了作为Editor的content的DiagramRootContent对象上才能被显示出来。因此,我们要想再追加显示一个HelloWorldModel对象,实际上就是要给这个content对象加一个HelloWorldModel子模型。所以我们可以得出:这里的操作是安放在content模型对象上的,也就是:DiagramRootContentEditPart上。
按照前面在介绍更改结点大小和位置时讲过的,要想实现一个操作,我们就需要:安装一个Policy-->返回一个command-->实现对应的command。下面我们还是照着这个路子来。
首先还是选择合适的Policy。这里要添加子模型,可以猜想跟容器相关,所以选择的Policy为:ContainerEditPolicy。首先创建一个ContainerEditPolicy的子类:DiagramContainerEditPolicy。然后在DiagramRootContentEditPart上安装这个Policy。如下:

installEditPolicy(EditPolicy.CONTAINER_ROLE, new DiagramContainerEditPolicy());

下面我们先实现这个添加命令,最后再返过头来实现这个EditPolicy。
实现命令其实很简单:可以知道,我们需要有一个DiagramRootContentEditPart对象用作容器,需要有一个HelloWorldModel代表要添加的结点。具体实现就不写了。大约就是这个意思。然后实现我们的EditPolicy。如下:

public class DiagramContainerEditPolicy extends ContainerEditPolicy {

 

      @Override

      protected Command getCreateCommand(CreateRequest request) {

            AddHelloWorldCommand command = new AddHelloWorldCommand(

                        (DiagramRootContent) getHost().getModel(),

                        (HelloWorldModel) request.getNewObject());

            return command;

      }

 

}

现在可以试一下效果了:在调色析里选择HelloWorld,然后在Editor上可以看到允许操作的鼠标手势。只是此时点下去并没图显示出来。还是那个问题:需要刷新画面。
过程和之前讲到刷新控件大小和位置的方式一样:
修改DiagramRootContent的addChild()和removeChild()方法如下:

      public static final String P_CHILDREN = "p_children";

      public void addChild(HelloWorldModel child) {

            if (!children.contains(child)) {

                  children.add(child);

                  firePropertyChange(P_CHILDREN, null, child);

            }

      }

 

      public void removeChild(HelloWorldModel child) {

            if (children.contains(child)) {

                  children.remove(child);

                  firePropertyChange(P_CHILDREN, child, null);

            }

      }

让DiagramRootContentEditPart实现接口:PropertyChangeListener。propertyChange()方法实现如下:

      public void propertyChange(PropertyChangeEvent evt) {

            if(evt.getPropertyName().equals(DiagramRootContent.P_CHILDREN)){

                  refreshChildren();

            }

      }

在GEF中,默认已经有很多刷新方法的实现,我们可以直接调用,例如这里的refreshChildren(),前面介绍过的refreshVisuals()和后面将要介绍的刷新连接的方法。这些方法我们在属性改变时可以直接调用。
最后把监听事件加上,所以需要重写方法:active()和deactive(),如下:

      @Override

      public void activate() {

            super.activate();

            ((DiagramRootContent)getModel()).addPropertyChangeListener(this);

      }

     

      @Override

      public void deactivate() {

            ((DiagramRootContent)getModel()).removePropertyChangeListener(this);

            super.deactivate();

      }

Ok,let's try it again! look:

addChild1

图一

呵呵,图已经被成功加上。只是有一点:每次都加在重一位置。回想一下:我们在建一个新的模型时,没有给他设置一个位置,因此用的都是我们缺省定义的位置,所以每次都被加到同一位置上去了。

这个修改很容易,就是修改DiagramContainerEditPolicy的getCreateCommand()方法,让它再传一个位置参数给AddHelloWorldCommand,修改后最终的代码如下:

public class DiagramContainerEditPolicy extends ContainerEditPolicy {

 

      @Override

      protected Command getCreateCommand(CreateRequest request) {

            AddHelloWorldCommand command = new AddHelloWorldCommand(

                        (DiagramRootContent) getHost().getModel(),

                        (HelloWorldModel) request.getNewObject());

            command.setLocation(request.getLocation());

            return command;

      }

 

}

和:

public class AddHelloWorldCommand extends Command {

 

      private DiagramRootContent content;

      private HelloWorldModel model;

 

      public AddHelloWorldCommand(DiagramRootContent content,

                  HelloWorldModel model) {

            super();

            this.content = content;

            this.model = model;

      }

 

      @Override

      public void execute() {

            content.addChild(model);

      }

 

      @Override

      public void undo() {

            content.removeChild(model);

      }

 

      public void setLocation(Point location) {

            Rectangle constraints = model.getConstraints();

            constraints.setLocation(location);

      }

 

}

OK,现在再试一下:

addChild2

图二

现在图形被加到了正确的位置上了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics