GEF理解系列二

系列一中,我们完成了一个MVC结构,并初步构造了一个Editor,不过到现在Editor里什么东西都还没有,这节中我们要给它加一点东西。

一、配置和初始化Editor

要想让Editor真正开始工作,我们就需要做一些基础工作了。我们可以看到,当我们写了一个继承自GraphicalEditorWithPalette类的editor时,默认有几个方法需要实现。其中有一个方法:initializeGraphicalViewer()。看名字就知道这是一个用来初始化editor的方法。比如说editor一打开有什么内容等等就是在这里做的,我们可以给它加一个HelloWorldModel。另外,我们在系列一最后部分创建了一个EditPartFactory,我们需要把它配置到我们的Editor上去,这个也可以在initializeGraphicalViewer()方法里完成。不过,这里我们可以实现另一个方法:configureGraphicalViewer()。在那里完成也行。这里因此最后我们还需要配置一些东西,所以EditPartFactory就在方法configureGraphicalViewer()里完成。这样,内容分别如下:
  @Override
 protected void initializeGraphicalViewer() {
  getGraphicalViewer().setContents(new HelloWorldModel());
 }
 @Override
 protected void configureGraphicalViewer() {
  super.configureGraphicalViewer();
  getGraphicalViewer().setEditPartFactory(new DiagramEditPartFactory());
 }

简单来说:initializeGraphicalViewer里实现一些初始化的的东西,例如内容;configureGraphicalViewer实现一些配置的东西,例如factory,rootpane。

我们看一下此时的效果:

editor2

图一

呵呵,已经出了一个图了。只是有点死板而已。好像图有点大。下面我们来做一些改变(临时方式)。

在系列一,我们最后修改了一下HelloWorldModel,给它添加了一个属性constraint,用来设置图形的大小和位置。这里我们就要用到它了。

首先我们修改一下HelloWorldEditPart的createFigure()方法,追加一句,如下:label.setBounds(helloworld.getConstraints());
再运行,发现效果还是没变化。这是因为Editor默认的rootEditPart是ScalableRootEditPart,看doc里描述这种类型的RootEditPart会自动让图层填满整个空间。我们把它修改一下即可。在Editor的configureGraphicalViewer()方法里追加一句:getGraphicalViewer().setRootEditPart(new ScalableFreeformRootEditPart());即可,这是一个支持伸缩功能的RootEditPart,一般情况下我们都可以以此对象作为RootEditPart。
再运行看效果:

editor3

图二

呵呵,已经有点样子。不过现在的问题就是加来加去,也只加一个图形。要怎么才能加更多的图形呢?

二、创建多层结构

为了能添加更多的图形,我们需要再创建一层模型,用来包括0个或多个HelloWorldModel,然后把这个新模型作为Editor的contents。暂且把我们的新的模型命名为:DiagramRootContent。一般来说我们都可以通过多加一些对象层来实现对多个对象的组合、分拆,例如对于一个类模型,我们可以直接用类模型管理变量和方法,也可以新增加一个是间层:方法层和变量层;类只关心这两个层,然后让它们分别关心变量和方法, 这样整个模型结构会显得更清淅。

多了不说,因为新增加了对象,还是那三部曲重写一次过程。不过需要多说一点是:因为这个新的模型只是一个用来包含其他模型的容器,因此显然:需要有一个用来指示所有的子模型的变量和分别用来增加了移除子模型的方法。好,这差不多就够了。先写出来再说:
public class DiagramRootContent {
 private List<HelloWorldModel> children = new ArrayList<HelloWorldModel>();
 public void addChild(HelloWorldModel child) {
  if (!children.contains(child)) {
   children.add(child);
  }
 }
 public void removeChild(HelloWorldModel child) {
  if (children.contains(child)) {
   children.remove(child);
  }
 }
 public List<HelloWorldModel> getChildren(){
  return children;
 }
}
 
再创建一个对应的EditPart。
public class DiagramRootContentEditPart extends AbstractGraphicalEditPart {
 @Override
 protected IFigure createFigure() {
  ScalableFreeformLayeredPane layer = new ScalableFreeformLayeredPane();
  layer.setLayoutManager(new FreeformLayout());
  return layer;
 }
 @Override
 protected void createEditPolicies() {
 }
}

一个好的实践是对于每个Model,都实现对应的Editpart。

这里要注意:和SWT一样,容器的Figure要记得设置布局,要不子元素可能就显示不出来了。这里我设置的是FreeformLayout。
最后,在EditPartFactory里追加一段,用于关联这些对象:
if(model instanceof DiagramRootContent){
   DiagramRootContentEditPart editPart = new DiagramRootContentEditPart();
   editPart.setModel(model);
   return editPart;
 }
 
好了,一个新模型的MVC结构就定义好了。最后,为了让Editor显示这个新的内容,我们还是修改Editor的initializeGraphicalViewer()方法。例如:
 @Override
 protected void initializeGraphicalViewer() {
  HelloWorldModel model1 = new HelloWorldModel();
  model1.setConstraints(new Rectangle(0,0,100,20));
  
  HelloWorldModel model2 = new HelloWorldModel();
  model2.setConstraints(new Rectangle(100,50,100,20));
  
  HelloWorldModel model3 = new HelloWorldModel();
  model3.setConstraints(new Rectangle(50,100,100,20));
  
  DiagramRootContent content = new DiagramRootContent();
  content.addChild(model1);
  content.addChild(model2);
  content.addChild(model3);
  getGraphicalViewer().setContents(content);
 }
 
运行一下试试。有效果吗?好像没有。为什么没有呢?

在GEF中,有一些“关键”方法的存在。正是因为这些“关键”方法的存在才使得我们能够正确的完成各种任务。关键一词我打个引号,因为是我自己的理解。
回想一下上面:我们的确构造了一个content模型,里面的确有一个属性用来存所有的子模型。但是这只是我们自己的理解,GEF怎么知道是哪个属性代表所有的子模型呢?我们得有一个地方告诉它啊。对吧?有道理没?其实这样的地方有很多的,比如说后面要讲到连接。先不扯远了,把当前的事情 做完。
我们再看看Content的EditPart。看看还有没有什么其他的方法需要重写。有一个:getModelChildren()。意思就是说得到模型的子。不要选成了getChildren()哦。就像后面的连接一样,也要选getModel**,这个稍记一下就行了。
好了,重写这个方法如下:
 @Override
 protected List<HelloWorldModel> getModelChildren() {
  return ((DiagramRootContent)getModel()).getChildren();
 }
 
再运行一下:

editor4

图3

OK,图形成功被显示出来了。

这一部分就到这,接下来就是讲更进一步的内容了。

小提示:如果以上过程中,图出来显示的不一样,或者是图不出来。那有可能是你的图元选择不一样,或者是图元设置不一样。比如说透明之类的。 (废话)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值