专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » eclipsegef:[Eclipse]GEF入门系列( 3、应用例子) »正文

eclipsegef:[Eclipse]GEF入门系列( 3、应用例子)

来源: 发布时间:星期四, 2009年1月8日 浏览:91次 评论:0
  构造个GEF应用通常分为这么几个步骤:设计模型、设计EditPart和Figure、设计EditPolicy和Command其中 EditPart是最主要部分在实现它时候不可避免要使用到EditPolicy而后者又涉及到Command

  现在我们来看个例子功能非常简单用户可以在画布上增加节点(Node)和节点间连接可以直接编辑节点名称以及改变节点位置用户可以撤消/重做任何操作个树状大纲视图和个属性页这是个Eclipse项目打包文件在Eclipse里导入后运行Run-time Workbench新建个扩展名为"gefpractice"文件就会打开这个编辑器

  图1 Practice Editor使用界面

CombinedTemplateCreationEntry("Node", "Create a Node", Node., SimpleFactory(Node.), null, null);

  在新3.0版本GEF里还提供了种可以自动隐藏调色板编辑器GraphicalEditorWithFlyoutPalette对调色板外观有更多选项可以选择以后帖子里可能会提到如何使用

  调色板化操作应该放在initializePaletteViewer里完成最主要任务是为调色板所在 EditPartViewer添加拖动源事件支持前面我们已经为画布所在EditPartViewer添加了拖动目标事件所以现在就可以实现完整拖放操作了这里稍微讲解下拖放实现原理以用来创建节点对象节点工具为例它在调色板里是个 CombinedTemplateCreationEntry在创建这个PaletteEntry时(见上面代码)我们指定该对象对应个 Node.所以在用户从调色板里拖动这个工具时内存里有个TemplateTransfer单例对象会记录下Node.(称作 template)当用户在画布上松开鼠标时拖放结束事件被触发将由画布注册 DiagramTemplateTransferDropTargetListener对象来处理template对象(现在是Node.)在例子中我们处理思路方法是用个名为ElementFactory对象负责根据这个template创建个对应类型例子

  以上我们建立了模型和用于实现视图Editor模型改变都是由Command对象直接修改所以下面我们先来看都有哪些 Command由需求可知我们对模型操作有增加/删除节点、修改节点名称、改变节点位置和增加/删除连接等所以对应就有 CreateNodeCommand、DeleteNodeCommand、RenameNodeCommand、MoveNodeCommand、 CreateConnectionCommand和DeleteConnectionCommand这些对象它们都放归类在commands包里个 Command对象里最重要当然是execute思路方法了也就是执行命令思路方法除此以外要实现撤消/重做功能所以在Command对象里都有Undo和Redo思路方法同时在Command对象里要有成员变量负责保留执行该命令时相关状态例如RenameNodeCommand 里要有oldName和Name两个变量这样才能正确执行Undo和Redo思路方法要记住每个被执行过Command对象例子都是被保存在EditDoCommandStack中

  例子里EditPolicy都放在policies包里和图形有关(GraphicalEditPart子类)有 DiagramLayoutEditPolicy、NodeDirectEditPolicy和 NodeGraphicalNodeEditPolicy另外两个则是和图形无关编辑策略可以看到在后种类型两个类(ConnectionEditPolicy和NodeEditPolicy)中我们只覆盖了createDeleteCommand思路方法该思路方法用于创建个负责"删除"操作Command对象并返回要搞清这个思路方法看似矛盾名字里create和delete是对区别对象而言

  有了Command和EditPolicy现在可以来看看EditPart部分了个模型对象都对应个EditPart所以我们 3个模型对象(Element不算)分别对应DiagramPart、ConnectionPart和NodePart对于含有子元素EditPart必须覆盖getModelChildren思路方法返回子对象列表例如DiagramPart里这个思路方法返回是Diagram对象包含Node对象列表

  每个EditPart都有active和deactive两个思路方法般我们在前者里注册监听器(实现了 PropertyChangeListener接口所以EditPart本身就是监听器)到模型对象在后者里将监听器从列表里移除在触发监听器事件propertyChange思路方法里般是根据"事件名"称决定使用何种方式刷新视图例如对于NodePart如果是节点本身属性发生变化refreshVisuals思路方法若是和它相关连接发生变化refreshTargetConnections或 refreshSourceConnections这里用到事件名称都是我们自己来规定在例子中比如Node.PROP_NAME表示节点名称属性Node.PROP_LOCATION表示节点位置属性等等

  EditPart(确切说是AbstractGraphicalEditpart)另外个需要实现重要思路方法是createFigure这个思路方法应该返回模型在视图中图形表示个IFigure类型对象般都把这些图形放在figures包里例子里只有NodeFigure个自定义图形Diagram对象对应是GEF自带名为FreeformLayer图形它是个可以在东南西北 4个方向任意扩展层图形;而 Connection对应也是GEF自带图形名为PolylineConnection这个图形缺省是条用来连接另外两个图形直线在例子里我们通过TargetDecoration思路方法让连接目标端显示个箭头

  最后要为EditPart增加适当EditPolicy这是通过覆盖EditPartcreateEditPolicies思路方法来实现个被"安装"到EditPart中EditPolicy都对应个用来表示角色(Role)对于在模型中有子元素 EditPart般都会安装个EditPolicy.LAYOUT_ROLE角色EditPolicy(见下面代码)后者多为 LayoutEditPolicy子类;对于连接类型EditPart般要安装 EditPolicy.CONNECTION_ENDPOINTS_ROLE角色EditPolicy后者则多为 ConnectionEndpoEditPolicy或其子类等等



EditPolicy(EditPolicy.LAYOUT_ROLE, DiagramLayoutEditPolicy);

  用户操作会被当前工具(缺省为选择工具SelectionTool)转换为请求(Request)请求根据类型被分发到目标EditPart所安装EditPolicy后者根据请求对应角色来判断是否应该创建命令并执行

  在以前帖子里说过Role-EditPolicy-Command这样设计主要是为了尽量重用代码例如同个EditPolicy可以被安装在区别EditPart中而同个Command可以被区别EditPolicy所使用等等当然凡事有利必有弊我认为这种设计也有缺点首先在代码上看来不够直观你必须对众多Role、EditPolicy有所了解增加了学习周期;另外大部分不需要重用代码也要按照这个相对复杂方式来写带来了额外工作量

  以上就是个GEF应用里最基本几个组成部分例子中还有如Direct Edit、属性表和大纲视图等些功能没有讲解下面帖子里将介绍这些常用功能实现



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: