`
LuChar
  • 浏览: 75060 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

GEF原理及实现系列(四、控制器)

    博客分类:
  • GEF
阅读更多
控制器是GEF框架的核心,它负责模型和视图之间的通信。
1.控制器的功能
在GEF的MVC结构里,控制器是模型与视图之间的桥梁,也是整个GEF的核心,它不仅要监听模型的变化,当用户编辑视图时,还要把编辑结果反应到模型上。
在GEF中,控制器是由一组EditPart对象共同组成的,每一个模型对象都对应一个EditPart对象。应用程序中需要有一个EditPartFactory对象负责根据给定模型对象创建对应的EditPart对象,这个工厂类将在创建模型时被调用。
控制器是GEF中最复杂的一部分,GEF把控制器完成的工作又分成了几个部分,包括请求和编辑策略及引申出来的命令模式,如下图:

用户的编辑操作被转换为一系列请求(Request),Eclipse中有很多种类的请求,这些种类在GEF里被成为角色(Role)。在GEF里有图形 化和非图形化这两大类角色,前者如“LayoutRole”对应和布局有关的操作,后者如“ConnectionRole”对应和连接有关的操作等。角色 这个概念是通过编辑策略(EditPolicy)来实现的,EditPolicy的主要功能是根据请求创建相应的命令(Command),而后者会直接操 作模型对象。
对每一个EditPart,用户都可以“安装”一些EditPolicy。用户对这个EditPart的特定操作会被交给已安装的对应EditPolicy处理。这样做的直接好处是可以在不同EditPart之间共享一些重复操作。
2.控制器的实现
        每一个模型都会对应一个控制器,控制器主要负责模型和视图的同步。控制器要监听模型的属性改变的事件,并通知视图更新。另外,控制器还要设置相应的编辑策略,用来处理由视图接收的请求。
实现一个EditPart一般来说需要重载performRequest、getCommand、 activate、deactivate和refreshVisuals函数,并实现createEditPolicies、createFigure接 口函数,为了让EditPart能够成为PropertyChangeListener,你还必须实现PropertyChangeListener接 口。performRequest和getCommand将在第3节介绍,activate和deactivate用于处理当EditPart处于激活或 者非激活状态时的操作,一般来说,可以在这两个函数中注册和移除自己监听者的角色。refreshVisuals函数用于更新自己的视图。
java 代码
  1. package com.example.parts;
  2. import java.beans.PropertyChangeEvent;
  3. import java.beans.PropertyChangeListener;
  4. import java.util.List;
  5. import org.eclipse.draw2d.ChopboxAnchor;
  6. import org.eclipse.draw2d.ConnectionAnchor;
  7. import org.eclipse.draw2d.IFigure;
  8. import org.eclipse.draw2d.geometry.Dimension;
  9. import org.eclipse.draw2d.geometry.Point;
  10. import org.eclipse.draw2d.geometry.Rectangle;
  11. import org.eclipse.gef.ConnectionEditPart;
  12. import org.eclipse.gef.EditPolicy;
  13. import org.eclipse.gef.GraphicalEditPart;
  14. import org.eclipse.gef.NodeEditPart;
  15. import org.eclipse.gef.Request;
  16. import org.eclipse.gef.RequestConstants;
  17. import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
  18. import org.eclipse.gef.tools.DirectEditManager;
  19. import org.eclipse.jface.viewers.TextCellEditor;
  20. import com.example.figures.NodeFigure;
  21. import com.example.model.Node;
  22. import com.example.policies.NodeDirectEditPolicy;
  23. import com.example.policies.NodeEditPolicy;
  24. import com.example.policies.NodeGraphicalNodeEditPolicy;
  25. public class NodePart extends AbstractGraphicalEditPart implements PropertyChangeListener, NodeEditPart {
  26. protected DirectEditManager manager;
  27. //处理请求
  28. public void performRequest(Request req) {
  29. if (req.getType().equals(RequestConstants.REQ_DIRECT_EDIT)) {
  30. if (manager == null) {
  31. NodeFigure figure = (NodeFigure) getFigure();
  32. manager = new NodeDirectEditManager(this, TextCellEditor.class, new NodeCellEditorLocator(figure));
  33. }
  34. manager.show();
  35. }
  36. }
  37. //监听模型属性改变
  38. public void propertyChange(PropertyChangeEvent evt) {
  39. if (evt.getPropertyName().equals(Node.PROP_LOCATION))
  40. //更新视图
  41. refreshVisuals();
  42. else if (evt.getPropertyName().equals(Node.PROP_NAME))
  43. refreshVisuals();
  44. else if (evt.getPropertyName().equals(Node.PROP_INPUTS))
  45. //更新连接
  46. refreshTargetConnections();
  47. else if (evt.getPropertyName().equals(Node.PROP_OUTPUTS))
  48. refreshSourceConnections();
  49. }
  50. //创建模型对应的视图
  51. protected IFigure createFigure() {
  52. return new NodeFigure();
  53. }
  54. //设置编辑策略
  55. protected void createEditPolicies() {
  56. installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new NodeDirectEditPolicy());
  57. installEditPolicy(EditPolicy.COMPONENT_ROLE, new NodeEditPolicy());
  58. installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new NodeGraphicalNodeEditPolicy());
  59. }
  60. //注册自己成为模型的监听器
  61. public void activate() {
  62. if (isActive()) {
  63. return;
  64. }
  65. super.activate();
  66. ((Node) getModel()).addPropertyChangeListener(this);
  67. }
  68. //把自己从模型的监听器中删除
  69. public void deactivate() {
  70. if (!isActive()) {
  71. return;
  72. }
  73. super.deactivate();
  74. ((Node) getModel()).removePropertyChangeListener(this);
  75. }
  76. //更新视图的显示
  77. protected void refreshVisuals() {
  78. Node node = (Node) getModel();
  79. Point loc = node.getLocation();
  80. Dimension size = new Dimension(150, 40);
  81. Rectangle rectangle = new Rectangle(loc, size);
  82. ((NodeFigure) this.getFigure()).setName(((Node) this.getModel()).getName());
  83. ((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), rectangle);
  84. }
  85. //------------------------------------------------------------------------
  86. // Abstract methods from NodeEditPart
  87. //得到源连接的连接点
  88. public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) {
  89. return new ChopboxAnchor(getFigure());
  90. }
  91. public ConnectionAnchor getSourceConnectionAnchor(Request request) {
  92. return new ChopboxAnchor(getFigure());
  93. }
  94. //得到目标连接的连接点
  95. public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) {
  96. return new ChopboxAnchor(getFigure());
  97. }
  98. public ConnectionAnchor getTargetConnectionAnchor(Request request) {
  99. return new ChopboxAnchor(getFigure());
  100. }
  101. //得到以模型作为源的连接列表
  102. protected List getModelSourceConnections() {
  103. return ((Node) this.getModel()).getOutgoingConnections();
  104. }
  105. //得到以模型作为目标的连接列表
  106. protected List getModelTargetConnections() {
  107. return ((Node) this.getModel()).getIncomingConnections();
  108. }
  109. }
EditPart(确切的说是AbstractGraphicalEditpart)另外一个需要实现的重要方法是createFigure(), 这个方法应该返回模型在视图中的图形表示,是一个IFigure类型对象。一般都把这些图形放在figures包里,例子里只有NodeFigure一个 自定义图形,Diagram对象对应的是GEF自带的名为FreeformLayer的图形,它是一个可以在东南西北四个方向任意扩展的层图形;而 Connection对应的也是GEF自带的图形,名为PolylineConnection,这个图形缺省是一条用来连接另外两个图形的直线,在例子里 我们通过setTargetDecoration()方法让连接的目标端显示一个箭头。

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

installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramLayoutEditPolicy());

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

    在GEF里,这个弹出的编辑器由DirectEditManager类负责管理,在我们的NodePart类里,通过覆盖 performRequest()方法响应用户的DirectEdit请求,在这个方法里一般要构造一个DirectEditManager类的实例(例 子中的NodeDirectEditManager),并传入必要的参数,包括接受请求的EditPart(就是自己,this)、编辑器类型(使用 TextCellEditor)以及用来定位编辑器的CellEditorLocator(NodeCellEditorLocator),然后用 show()方法使编辑器显示出来,而编辑器中显示的内容已经在构造方法里得到。简单看一下NodeCellEditorLocator类,它的关键方法 在relocate()里,当编辑器里的内容改变时,这个方法被调用从而让编辑器始终处于正确的坐标位置。DirectEditManager有一个重要 的initCellEditor()方法,它的主要作用是设置编辑器的初始值。在我们的例子里,初始值设置为被编辑NodePart对应模型 (Node)的name属性值;这里还另外完成了设置编辑器字体和选中全部文字(selectAll)的功能,因为这样更符合一般使用习惯。

        在NodePart里还要增加一个角色为DIRECT_EDIT_ROLE的EditPolicy,它应该继承自 DirectEditPolicy,有两个方法需要实现:getDirectEditCommand()和showCurrentEditValue (),虽然还未遇到过,但前者的作用你不应该感到陌生--在编辑结束时生成一个Command对象将修改结果作用到模型;后者的目的是更新Figure中 的显示,虽然我们的编辑器覆盖了Figure中的文本,似乎并不需要管Figure的显示,但在编辑中时刻保持这两个文本的一致才不会出现"盖不住"的情 况,例如当编辑器里的文本较短时。

        上例通过继承AbstractGraphicalEditPart类实现了一个EditPart,另外,当GEF框架创建一个模型时,都会为此模型创建一 个对应的控制器。创建控制器的操作是在控制器工厂中完成的,用户可以在编辑器初始化时指定控制器工厂,例如:“getGraphicalViewer ().setEditPartFactory(new PartFactory())”,其中PartFactory为控制器工厂,代码如下:
java 代码
  1. /*
  2. * Created on 2005-1-24
  3. *
  4. * TODO To change the template for this generated file go to
  5. * Window - Preferences - Java - Code Style - Code Templates
  6. */
  7. package com.example.parts;
  8. import org.eclipse.gef.EditPart;
  9. import org.eclipse.gef.EditPartFactory;
  10. import com.example.model.Connection;
  11. import com.example.model.Diagram;
  12. public class PartFactory implements EditPartFactory {
  13. public EditPart createEditPart(EditPart context, Object model) {
  14. EditPart part = null;
  15. //根据模型创建相应的EditPart
  16. if (model instanceof Diagram)
  17. part = new DiagramPart();
  18. else if (model instanceof Connection)
  19. part = new ConnectionPart();
  20. else
  21. part = new NodePart();
  22. //设置EditPart对应的模型
  23. part.setModel(model);
  24. //返回根据模型创建的EditPart
  25. return part;
  26. }
  27. }

通过创建控制器和控制器工厂,GEF编辑器将会知道在模型创建后,自动调用控制器工厂创建对应的空气,从而实现模型和控制器的一一对应关系。
分享到:
评论

相关推荐

    停车场管理系统c语言.docx

    问题描述: 停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在停车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入; 当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。 1.基本要求 (1)以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。 (2)每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去;则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。 (3)栈以顺序结构实现,队列以链表实现。 2.重点难点 重点:针对停车场问题的特点,利

    精选毕设项目-人民好公仆小程序(生活+便民+政务).zip

    精选毕设项目-人民好公仆小程序(生活+便民+政务)

    精选毕设项目-相册;处理用户信息.zip

    精选毕设项目-相册;处理用户信息

    精选毕设项目-喵喵小说.zip

    精选毕设项目-喵喵小说

    精选毕设项目-图片预览带后端.zip

    精选毕设项目-图片预览带后端

    精选项目-爱靓女带后台.zip

    精选项目-爱靓女带后台

    法院综合安全监管平台解决方案PPT(53页).pptx

    在科技与司法的交响曲中,智慧法院应运而生,成为新时代司法服务的新篇章。它不仅仅是一个概念,更是对法院传统工作模式的一次深刻变革。智慧法院通过移动信息化技术,为法院系统注入了强大的生命力,有效缓解了案多人少的矛盾,让司法服务更加高效、便捷。 立案、调解、审判,每一个阶段都融入了科技的智慧。在立案阶段,智慧法院利用区块链技术实现可信存证,确保了电子合同的合法性和安全性,让交易双方的身份真实性、交易安全性得到了有力见证。这不仅极大地缩短了立案时间,还为后续审判工作奠定了坚实的基础。在调解阶段,多元调解服务平台借助人工智能、自然语言处理等前沿技术,实现了矛盾纠纷的快速化解。无论是矛盾类型的多元化,还是化解主体的多元化,智慧法院都能提供一站式、全方位的服务,让纠纷解决更加高效、和谐。而在审判阶段,智能立案、智能送达、智能庭审、智能判决等一系列智能化手段的应用,更是让审判活动变得更加智能化、集约化。这不仅提高了审判效率,还确保了审判质量的稳步提升。 更为引人注目的是,智慧法院还构建了一套完善的执行体系。移动执行指挥云平台的建设,让执行工作变得更加精准、高效。执行指挥中心和信息管理中心的一体化应用,实现了信息的实时传输和交换,为执行工作提供了强有力的支撑。而执行指挥车的配备,更是让执行现场通讯信号得到了有力保障,应急通讯能力得到了显著提升。这一系列创新举措的实施,不仅让执行难问题得到了有效解决,还为构建诚信社会、保障金融法治化营商环境提供了有力支撑。智慧法院的出现,让司法服务更加贴近民心,让公平正义的阳光更加温暖人心。

    西门子1200与3台台达DTK温控器通讯程序 功能:实现西门子1200 PLC对3台台达DTK温控器进行485通讯控制,在触摸屏上设定温度,读取温度 器件:西门子12

    西门子1200与3台台达DTK温控器通讯程序 功能:实现西门子1200 PLC对3台台达DTK温控器进行485通讯控制,在触摸屏上设定温度,读取温度 器件:西门子1200 1214DC DC DC.昆仑通态TPC7062Ti ,西门子KTP700 Basic PN,台达DTK 4848V12温控器。 说明:的是程序,带详细注释程序,西门子触摸屏程序,PLC设置和温控器设置,接线说明书。 #SIEMENS 西门子

    机械设计电阻绕线焊线一体机sw18全套技术资料100%好用.zip

    机械设计电阻绕线焊线一体机sw18全套技术资料100%好用.zip

    VB6编写的上位机采集2路温度 并形成曲线图 还可查看历史数据

    VB6编写的上位机源码,可实时显示曲线图,带有数据库,可以进行历史数据的保存 及 查看历史采集数据。

    精选毕设项目-新浪读书.zip

    精选毕设项目-新浪读书

    jQuery+Slick插件实现游戏人物轮播展示切换特效源码.zip

    jQuery+Slick插件实现游戏人物轮播展示切换特效源码是一款通过背景图片的切换来显示不同的人物效果,轮播效果通过slick幻灯片插件来制作。效果非常棒,有需要的朋友可以直接下载使用,适应各大网站

    精选毕设项目-地图查找附件.zip

    精选毕设项目-地图查找附件

    (蛐蛐voc数据)农作物病虫害识别目标检测数据集,VOC格式,蛐蛐数据集,纯手动标注,用来进行目标检测代码训练的数据

    (蛐蛐voc数据)农作物病虫害识别目标检测数据集,VOC格式,蛐蛐数据集,纯手动标注,用来进行目标检测代码训练的数据。

    MATLAB Simulink仿真模型 双馈风机并网频率控制仿真模型,利用下垂控制与惯性控制结合的综合惯性控制,实现电力系统的频率稳定,两台同步发电机组,具体参数可自行调节,频率波形比较可利用matl

    MATLAB Simulink仿真模型 双馈风机并网频率控制仿真模型,利用下垂控制与惯性控制结合的综合惯性控制,实现电力系统的频率稳定,两台同步发电机组,具体参数可自行调节,频率波形比较可利用matlab工作区画出。

    科研项目结题报告的撰写指南:结构、内容与注意事项

    一、结题报告的类型及主要结构 结题报告是一种专门用于科研课题结题验收的实用性报告类文体,也叫研究报告。它是研究者在课题研究结束后对科研课题研究过程和研究成果进行客观、全面、实事求是的描述,是课题研究所有材料中最主要的材料,也是科研课题结题验收的主要依据。   一篇规范、合格的结题报告,需要回答好3个问题:一是“为什么要选择这项课题进行研究?”二是“这项课题是怎样进行研究的?”三是“课题研究取得哪些研究成果?”  基本结构大致包括以下部分: 第一个问题 “为什么要选择这项课题进行研究?”  1.课题提出的背景;2.课题研究的意义(包括理论意义和现实意义,这个部分也可以合并归入“课题提出的背景”部分);第二个问题“这项课题是怎样进行研究的?”3.文献综述;4.课题研究的理论依据;5.课题研究的目标;6.课题研究的主要内容;7.课题研究的对象;8.课题研究的方法;9. 课题研究的主要过程(研究的步骤);   除了第9部分外,从第1到第8部分在填报课题立项申报表、在制定课题研究方案、在开题报告中,都有要求,内容基本相同。到了撰写结题报告时,只须稍作适当修改就可以了。而第9部分,则需要通过对

    1+X网络安全应急响应之应急准备:构建高效安全的应急响应体系

    内容概要:本文档重点讲述了网络安全应急响应的各项准备工作,涵盖了‘1+X’网络安全应急响应的职业技能等级证书概述、应急响应的基础知识、应急响应组织的建立、风险评估与改进、应急响应预案的制定以及详细的应急响应计划处置样例。文中详细介绍了各级职业技能的要求和任务,尤其关注如何未雨绸缪,制定完善的应急预案以应对潜在的网络安全风险;同时也探讨了如何在网络安全事件发生时,采取及时有效的应急处置措施。 适合人群:从事或有兴趣进入网络安全领域的从业人员,尤其是准备考取‘1+X’网络安全应急响应职业技能等级证书的相关人员。 使用场景及目标:帮助读者了解网络安全应急响应的基本概念及其在整个国家安全框架中的重要地位;指导读者学会如何建立健全高效的应急响应组织结构,如何进行全面的风险评估以及如何编制切实可行的应急预案;通过实例剖析,增强读者应对突发网络安全事件的能力。文档的目标在于提升读者在不同层面的专业技能,包括但不限于系统备份、日志分析、安全漏洞修复等方面的能力。 阅读建议:此文档结构清晰,内容详尽,非常适合有一定基础的技术从业者参考学习。建议读者逐章节深入了解,特别是关注自身岗位对应的技能细分类别。此外,结合实例深入理解和练习如何进行应急处置是非常有价值的,有助于提升自身的实战能力。

    电动汽车动力系统匹配计算模型:输入整车参数及性能要求,一键生成驱动系统的扭矩功率峰值转速等参数 2、整车动力经济性计算模型:包含NEDC WLTC CLTC工况,输入整车参数可生成工况电耗、百公里电

    电动汽车动力系统匹配计算模型:输入整车参数及性能要求,一键生成驱动系统的扭矩功率峰值转速等参数。 2、整车动力经济性计算模型:包含NEDC WLTC CLTC工况,输入整车参数可生成工况电耗、百公里电耗、匀速工况续航、百公里电耗等信息。 实际项目中使用的计算仿真模型. 两个模型打包

    chromedriver-linux64_122.0.6254.0.zip

    chromedriver-linux64_122.0.6254.0

    SRS构型七自由度冗余机械臂运动学建模全套matlab代码 代码主要功能: 1. 基于臂角参数化方法求解机械臂在给定末端位姿和臂角下的关节角度; 2. 求解机械臂在给定末端位姿下的有效臂角范围

    SRS构型七自由度冗余机械臂运动学建模全套matlab代码 代码主要功能: [1]. 基于臂角参数化方法求解机械臂在给定末端位姿和臂角下的关节角度; [2]. 求解机械臂在给定末端位姿下的有效臂角范围,有效即在该区间内机械臂关节角度不会超出关节限位; [3]. 以避关节限位为目标在有效臂角区间内进行最优臂角的选取,进而获取机械臂在给定末端位姿下的最优关节角度。 购前须知: 1. 代码均为个人手写,主要包含运动学建模全套代码; 2. 代码已经包含必要的注释; 包含原理推导文档,不包含绘图脚本以及urdf;

Global site tag (gtag.js) - Google Analytics