最近在学习GEF,本例子主要是修改了八进制的例子。在这里做一下总结。先来介绍一下gef,网上关于GEF的介绍越来越多,从另一方面也说明这个技术确实在热起来,不过GEF为了实现可扩放性和可重用性,做的很是复杂(闲话一下,最近看了一本书《Better.Faster.Lighter.Java》,没看多少,Justin Gehtland, Bruce A. Tate写的,一开始就说了,为了满足越来越多的需要,各种framework,library,language都是越来越复杂了,学习曲线也变得陡峭了,这个似乎是无法避免的,java语言也是,不信去看看jdk,1.1时才3.7MB,1.4时已经38MB了。我也一直坚信,Simply the best,呵呵)。
GEF的一些资源:
1。www.eclipse.org 这个是源头啊,faq也可以看看
2。ibm的dW 除了相关文章,这里还有本关于gef和emf的红宝书,可以免费下载。
3。eclipseworld.org 这个是一个关于eclipse中文社区
4。八进制的blog http://bjzhanghao.cnblogs.com/ 。
5。这里还有些中文教程 http://www.benisoft.com/cn/index.htm
6。还有一些blog http://www.blogjava.net/hopeshared/ http://www.blogjava.net/eclipshine/ http://www.blogjava.net/reloadcn/ http://www.blogjava.net/USTCEric
好了,现在来介绍一下GEF的实现机制,主要是我的一些理解可能还有一不对的地方,欢迎大家帮我改正。
GEF是具有标准MVC(Model-View-Control)结构的图形编辑框架,其中Model由我们自己根据业务来设计,它要能够提供某种模型改变通知的机制,用来把Model的变化告诉Control层;Control层由一些EditPart实现,EditPart是整个GEF的核心部件;而 View层,大多数情况下,使用Draw2D实现了,其作用是把Model以图形化的方式表现给使用者,当然你也可以使用其他图形包,不过gef与 Draw2D的结合还是非常紧密的,一般为了使用方便,View都是使用Draw2D实现的。
关于Draw2D,八进制有一篇相应的文章,还有eclipse上的一篇文章,可以参考,这里有几点需要强调一下:
1。Draw2D提供了很多缺省图形,最常见的有三类:1、形状(Shape),如矩形、三角形、椭圆形等等;2、控件(Widget),如标签、按钮、滚动条等等;3、层(Layer),它们用来为放置于其中的图形提供缩放、滚动等功能。
2。每个图形都可以拥有一个边框(Border),Draw2D所提供的边框类型有GroupBoxBorder、TitleBarBorder、ImageBorder、 ButtonBorder,以及可以组合两种边框的CompoundBorder等等,在Draw2D里还专门有一个Insets类用来表示边框在图形中所占的位置,它包含上下左右四个整型数值。
3。一个图形可以包含很多个子图形,这些被包含的图形在显示的时候必须以某种方式被排列起来,负责这个任务的就是父图形的LayoutManager,相应的约束(Constraint)对象就在这里,比如在子图形刷新(refreshVisuals)时可以通过将其布局约束传递给其父元素来定位。
4。利用Draw2D中的Router、Anchor和Locator,可以实现多种连接样式。Router负责连接线的外观和操作方式;Anchor控制连接线端点在图形上的位置,即"锚点"的位置;Locator的作用是定位图形。
前面说过了GEF是通过MVC架构实现的,下面分别介绍这三个方面:
一、模型(Model):这个是相对比较容易理解,模型保存着业务逻辑,他是GEF这中唯一可以持久化的,并且需要提供相应的监听机制,来通知 EditPart去更新View,监听机制又可以分为分布式和集中式两种,我们可以针对域监听器进行转有通知,也可以全局广播;在这里我们认为 Command(EditPart用来更新模型的对象)也是模型的一个部分,因为它了解模型。此外,在有时候可能需要多种模型。我们对于业务模型,提供一个“视图”模型,这样便于实现和满足相应的要求,不管内部模型是怎么样的,都要实现通知机制。
二、视图。GEF提供了在EclipseWorkbench中使用Viewer,称为EditPartViewer。它的作用和jface中的 Viewer很相,不过这时候它的ContentProvider和LabelProvider是EditPart,通过setContents设置(注意在八进制代码中setContents参数为模型对象,通过分析发现,在AbstractEditPartViewer中此方法被重载,可以除了接受 org.eclipse.gef.editpart对象外可以接受Object对象,不过此时回调用EditPartFactory,通过给定的模型对象来创建相应的EditPart,个人认为这样做并不与“View与Model无直接联系”的要求相矛盾)。这个接口继承了 org.eclipse.jface.viewers.ISelectionProvider接口(这个也和jface中的viewer一样),因此使 viewer提供了监听器,这样可以将对view的操作传递到editpart。EditPartViewer会维护各个EditPart的选中状态,如果没有被选中的EditPart,则缺省选中的是作为contents的EditPart。
EditPartViewer可以适配到任何一个SWT控件,因为它要求有createControl方法,接受一个父SWT控件作为适配对象,从而将 GEF生成的Figure对象显示在这个SWT控件上,因此GEF可以使用任何图形包,不过GEF提供了对Draw2D的默认实现,比如 AbstractGraphicalEditPart类中的回调方法createFigure就要求返回一个IFigure对象。将一个GEF图形显示出来可以使用org.eclipse.ui.part.EditorPart也可以是org.eclipse.ui.part.ViewPart,如果使用 EditorPart,则需要实现继承自WorkbenchPart的createPartControl,如果是ViewPart则需要自己实现与 GEF的交互,不过Eclipse Workbench对viewpart和editorpart的支持是一样的,都是在plugin文件扩展相应的扩展点。一般来说,使用GEF对 Editorpart的模式实现是非常方便的。
GEF目前提供两种视图分别是GraphicalViewer和TreeViewer,都间接继承了EditPartViewer接口,前者利用 Draw2D图形(IFigure)作为表现方式,多用于编辑区域,后者则多用于实现大纲展示,并且他们有两个具体的实现,分别是 ScrollingGraphicalViewer和TreeViewer。其中ScrollingGraphicalViewer,通过分析GEF源代码可知,是GraphicalEditor中Viewer的默认实现,我们可以通过GraphicalEditor类提供的 setGraphicalViewer(GraphicalViewer)方法重新设置其他viewer。我们在使用的时候通过 configureGraphicalViewer和initializeGraphicalViewer方法来配置GraphicalViewer。所不同的是,在configureGraphicalViewer之后initializeGraphicalViewer之前插入了一个 hookGraphicalViewer方法,其作用是同步选择和把 EditPartViewer作为SelectionProvider注册到所在的site,使其成为SelectionProvider。
此外,GEF中还提供一种成为调色板(PaletteViewer)的视图,它也是间接实现了EditPartViewer接口。因此,我也像配置GraphicalViewer一样来配置PaletteViewer,类似的使用 configurePaletteViewer和initializePaletteViewer方法,其间类似的插入了一个 hookPaletteViewer方法,用于设置相应EditDomain的PaletteViewer。
最后,总结一下如何配置GraphicalView,主要是四个方面:
1。设置一个RootEditPart:RootEditPart的是使整个GEF框架运行起来的关键之一。RootEditPart并不对应于任何的模型对象,它将从setContents()方法中接收到的模型对象进行转换,并添加到整个的EditPart体系中去。
2。设置其EditPartFactory:负责从模型到EditPart的转换。一般来说一个模型对象对应于一个EditPart。
3。设置EditDomain:用来接收事件并选择恰当的事件处理函数进行处理,这个主要是为了相应view所接收到的用户的操作。
4。调用setContents()方法:为其设置要显示的内容。
三、控制器(EditPart)。这是GEF最核心的地方了,它将model和view联系起来。程序员可以继承三种EditPart,分别是 org.eclipse.gef.editparts.AbstractGraphicalEditPart,org.eclipse.gef.editparts.AbstractConnectionEditPart(AbstractGraphicalEditPart的子类)和org.eclipse.gef.editparts.AbstractTreeEditPart。EditPart 的生命周期当setContents时,将模型对象输入,此对象为顶层对象,通过它可以遍历所有的模型对象。:EditPartViewer配备有 EditPartFactory,EditPartViewer通过EditPartFactory构造相应的Contents EditPart。然后EditPartViewer中的每个EditPart通过EditPartFactory构造相应的子EditPart。当用户添加新的模型的时候,包含这些模型对象的所对应的EditPart将构造相应的EditPart作出相应。视图的构造和EditPart的构造是同时进行的,每当EditPart构造并添加到它的父EditPart后相应的view也做同样的事情,比如GraphicalEditor中就有 GraphicalViewer成员变量,在此edipart创建时回调用createPartControl,在这个方法中将会创建相应的view,并将其加入到父view中。
一旦用户丢弃了某些模型对象,相应的EditPart就会被丢弃。比如用户执行了删除操作,则相应的模型对象和相应的EditPart都被删除了,但用户撤销了删除操作而重新创建的EditPart与原来的EditPart是不同的,所以EditPart是不能保存长期信息的,应该交给模型去保存,并且 EditPart也是不能被Command所引用。
在具体使用时,应该先定一个Contents EditPart,它的父元素为EditPartViewer的RootEditPart。RootEditPart是EditPartView的 root,它将EditPartView和它的contents(一般认为是顶层模型对象所对应的EditPart)联系起来,RootEditPart 为用户的EditPart提供一致性的上下文(context)。并且,当没有被选中的模型EditPart时,顶层对象的EditPart是默认被选中的,而RootEditPart是不能被选中的或者定位的,甚至不能与用户相交互,他也就没有对应的模型对象。GEF提供了几个默认的 RootEditPart的实现:FreeformGraphicalRootEditPart,RootTreeEditPart, ScalableRootEditPart,ScalableFreeformRootEditPart(此类继承于 FreeformGraphicalRootEditPart,增加了缩放Zoom支持,提供了ZoomManager;增加了一个LayerPane: ScalableFreeformLayeredPane。),(原来还有个GraphicalRootEditPart,已经deprecated,用 ScalableRootEditPart代替)。这里要注意的是:
1)对于FreeformRootEditPart(以及它的子类 ScalableFreeformRootEditPart),它的Contents EditPart应该有一个org.eclipse.draw2d.FreeformFigure对象(比如FreeformLayer或FreeformLayeredPane)作为它的Figure。例如在我们的代码里,对应的就是在 DiagramPart中的createFigure方法,它返回了一个FreeformLayer对象。
2) FreeformGraphicalRootEditPart的Primery Layer没有使用draw2d的LayoutManager,并且,除非contents的figure是个freeform figure,否则不能正确的调整大小。
3)FreefromGraphicalRootEditPart使用FreeformViewport类作为它的primary figure,这个类必须和ScrollingGraphicalViewer使用。
4)ScalableRootEditPart使用 Viewport作为primery figure,这个类必须和ScrollingGraphicalViewer使用。
5)RootTreeEditPart是TreeViewer的RootEditPart。
Contents EditPart的图形一般是一个空面板,该面板将包含diagram的子图。
我们还要定义其他“视图”模型的EditPart,比如节点(node),连接(connection)。对于节点,是Graphical,可以继承 AbstractGraphicalEditPart。并且可以实现NodeEditPart接口,则可以支持源和目标的 ConnectionEditPart,使用Anchor,具体在下面有讲述。在这里,我们的代码的NodePart类中,重载了 refreshVisual方法,其中设置figure的布局约束是通过它的父元素来定位的,我不知道这是不是标准的方法,XYLayout使用的是 rectangle约束,如果长宽设为-1,表示为该图形提供理想大小。不要使用setBounds,XYLayout布局管理器可以保证对滚动条进行更新,并能将相对约束转化为绝对约束,如果长宽设置为-1,则能够将图形设置为理想的大小。此外,为了改进性能,我们可以将refreshVisual中有若干模型的分别刷新,或者设置是否需要刷新的开关。
对于连接,可以继承AbstractConnectionEditPart,这个抽象类已经实现了 ConnectionEditPart。和Node实现一样,通过refreshVisual方法将属性从模型映射到图形。连接也可以有约束,不过与前面的约束不尽相同。在这里,连接路由器(connection router)使用约束来是连接转向(bend)。需要注意的是,一个Connection EditPart的图形必须是一个draw2d的Connection,这样就引入了连接锚(Connection Anchor)。连接必须由连接锚(ConnectionAnchor)“锚定”在两端。因此,需要在连接EditPart或者节点EditPart中实现使用什么样的锚。缺省情况下,GEF使用节点EditPart通过实现NodeEditPart接口来提供锚。这是因为,锚的选择取决与各个节点上正在使用的图形,而连接EditPart不应了解节点上的图形,并且,当用户创建连接的时候,连接EditPart并没有创建,这时候就由节点自己显示反馈。这里需要注意的是:何时使用以及何时不使用ConnectionEditPart,当用户可以选择某些东西并可与之交互时,就需要 ConnectionEditPart。它可能与某行中的某个对象相对应,并且回自己删除;如果这是需要一个绘制直线的节点或者容器,那么只需要用图形的 paint方法绘制直线,或者组合一个图形,这个图形包含Polyline图形。连接必须要拥有源和目标。如果要创建一个连接,并且在没有源和目标存在的情况下,可以继承AbstractGraphicalEditPart,并使用连接图形,比如PolylineConnection。
正如前面说的,模型需要实现某种通知机制,各个EditPart要将自己做为监听者,注册在模型上,以便在模型发生改变的时候收到相应的通知。 当EditPart收到相应的通知时,调用相应的处理方法,来进行一次强制的刷新,对于模型对象的增减可以调用refreshChildren方法,对于简单属性的更改可以调用refreshVisuals方法,这时,像前面提到的,可以只刷新改变的部分,以提高性能。一般,我们在Activate方法中注册监听器,在Deactivate方法中注销监听器。
以上完成的是从模型到视图的映射,你还需要实现的是编辑策略Edit Policies,因为EditPart并不直接对模型进行编辑,每一个EditPolicy都针对一个特定的编辑任务或者一组相关的工作。这样的实现便于在不同的EditPart间重用(reuse)编辑行为,并且这样的实现,可以动态的改变行为,比如改变layout或者routing时。在 createEditPolicies方法中,我们要insall我们的的Policies,这时候就需要roles,roles的作用就是作为关键字来标示不同的policies。policy中提供Command,每个应用程序都有个Command栈,Command的运行要通过Command栈,而不是直接调用execute方法。
说到这里,要注意EditPartView是视图的,一般放在一个UI插件上比如EditorPart,viewPart,甚至swt控件。EditPart是控制器,联系视图和模型。
在本文的最后介绍一下GEF的运行机制:EditPartView接受用户的操作,如节点的移动,增删,每个节点对应一个EditPart对象,每个 EditPart都有一组由Role区分的EditPolicies,每个EditPolicy会对应一些Command对象,Command最终会对模型进行操作。用户的操作会转化为Request分配给特定的EditPolicy,由EditPolicy创建相应的Command对模型进行操作,这些 Command会保留在EditDomain的命令堆栈中,用于实现undo,redo功能,EditDomain是专门用于维护 EditPartView,Command信息的对象,一般每个EditPart有一个EditDomain。
以上就是对所作的GEF部分的大概描述,可能有些地方写的比较罗嗦,有的地方写的也可能不对,希望大家指出,谢谢。下面还要对RCP部分进行一些描述。
- 浏览: 7330699 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
发表评论
-
Equinox OSGi系列之三 Equinox配置参数详解(转)
2013-03-22 15:20 6951Eclipse不提示的解决办法 我们知道,在Eclips ... -
RCP自定义扩展点的应用
2010-05-06 14:21 3035打开plugin.xml文件中Extensi ... -
Nebula 的几个常用的widgets的使用
2010-05-06 14:15 5643package com.easyway.tbs.commons ... -
RCP GridViewer的学习应用
2010-05-05 21:47 4202package com.easyway.tbs.commons ... -
多项编辑页的学习应用
2010-05-05 20:41 2759package com.easyway.plugin.dev. ... -
gef中自身实现的常用功能的原理和实现
2010-04-23 21:35 2377在gef中关于常用功能对应的action在org.eclip ... -
gef中几何对齐功能原理以及实现
2010-04-23 21:34 2744几何对齐功能也是为了方便用户排列图形元素的,如果打开了此功 ... -
gef中打印功能的原理和实现
2010-04-23 21:33 2814在gef中关于打印的功能,采用PrintGraphicalV ... -
gef中采用公共的快捷键功能的原理和实现
2010-04-23 21:27 2560在gef相关的编辑器类中采用快捷键处理器KeyHandler ... -
gef 上下文菜单的应用
2010-04-23 21:26 2871在gef的编辑器视图中添加相关的上下文菜单,经常需要是实 ... -
网上流传的一个RCP Table Grid打印实现原理和局限性
2010-04-22 20:11 3253package com.easyway.tbs.common ... -
gef中编辑图中添加背景图片原理以及实现
2010-04-22 20:01 2917GEF的RootEditPart对应的Figure是一个 ... -
gef中将流程图转换图片复制粘贴原理以及实现
2010-04-22 19:59 2913设计思路如下:将一个gef图元转换为一个图片(create ... -
gef编辑器中需要采用向导页
2010-04-22 19:57 2634在一般的gef编辑器中需要采用向导页,生成一个格式的 ... -
gef中拖动拽动原理以及实现(一)
2010-04-22 19:49 3228gef中拖动拽动原理以及实现 方案一: 创 ... -
gef中添加可折叠调色板原理以及实现(二)
2010-04-22 19:47 3158gef中添加可折叠调色板原理以及实现 中主要的Palette ... -
gef中添加可折叠调色板原理以及实现(一)
2010-04-22 19:45 3148最近心情不好,写 ... -
RCP 线程的开发应用
2010-03-16 15:22 2429http://www.blogjava.net/gembin/ ... -
使用Eclipse自带的PropertySheet
2010-03-03 17:36 2714在项目中遇到一些小问 ... -
关于一个TableViewer的注解封装(转载)
2010-03-03 16:18 2806在项目你可能为多个TableViewer编写多个IC ...
相关推荐
**RCP(Rich Client Platform)** 是Eclipse项目的一个核心组成部分,它提供了一个框架,用于构建功能丰富的桌面应用程序。RCP允许开发者利用Java语言和Eclipse插件体系结构来创建可扩展、模块化的应用程序,这些...
RCP(Rich Client Platform)是Eclipse的一个核心组成部分,它提供了一个基础架构,用于创建功能丰富的桌面应用。RCP应用可以利用Eclipse的插件系统,使得开发者能够将应用程序拆分成多个模块,每个模块负责特定的...
在这个实例程序中,"RCP实例程序,可画层次结构图" 提供了一个使用RCP技术实现的能够绘制层次结构图的工具。这个程序不仅展示了RCP的基本应用,还结合了图形用户界面(GUI)的设计,使得用户能够直观地理解和操作...
Eclipse RCP是一个用于构建桌面应用程序的框架,它基于插件系统,可以方便地集成多种功能。在本教程中,GEF_RCP_DEMO展示了如何在RCP应用中集成GEF图形编辑功能。 8. **DEMO源码分析** GEF_RCP_DEMO的源码包含了...
总结来说,本文件详细说明了如何在GEF环境下创建一个简单的HelloWorld应用程序,包括RCP工程的建立、GEF结构的创建、Editor的实现等关键步骤。同时,还强调了使用合适JDK版本的重要性,以及对Windows平台用户的特定...
【标题】中的“RCP-Projects:基于RCP和GEF框架来实现的powerdesigner”指的是一个项目,该项目利用了Eclipse Rich Client Platform (RCP)和Graphical Editing Framework (GEF)来构建一个类似于PowerDesigner的工具。...
### GEF简易教程知识点详解 #### 一、GEF简介与环境配置 **GEF**,全称为**Graphical Editing Framework**,是Eclipse平台上用于创建复杂图形编辑器的框架。它提供了一套完整的工具集,使开发者能够构建具有图形化...
Eclipse Rich Client Platform (RCP) 是一个强大的框架,用于构建桌面应用程序,它基于Java,提供了丰富的用户界面和高度可定制的功能。Eclipse RCP 的核心理念是组件化和模块化,使得开发者能够构建功能丰富的应用...
"GEFApp"这个例子可能是通过创建一个简单的图形编辑场景来展示GEF的基本用法。比如,它可能包含一个画布,用户可以在上面绘制和编辑一些基本形状,如圆形、矩形,并能进行拖拽、缩放、旋转等操作。源码中会展示如何...
Eclipse RCP(Rich Client Platform)是一个开源框架,用于构建桌面应用程序。它允许开发者利用Java和Eclipse插件体系结构创建复杂、可扩展且用户友好的应用。在提供的压缩包中,包含了关于Eclipse RCP插件开发15至...
- `test.gef.demo`:可能是一个更复杂的示例,展示了如何在ViewPart中集成GEF,以及适配器扩展点的实现,可能包含属性页配置的逻辑。 通过学习这个示例代码,开发者可以了解如何在Eclipse RCP环境中有效地使用GEF...
- **EMF**:EMF(Eclipse Modeling Framework)是一个用于创建模型驱动的应用程序的框架,与GEF结合使用时能够处理复杂的模型数据。 #### 三、开发环境搭建 根据文档描述,开发环境主要包括以下组件: - **JDK**:...
- RCP(Rich Client Platform,富客户端平台)是Eclipse的一个子项目,用于构建功能丰富的桌面应用程序。 - RCP允许开发者使用Eclipse提供的UI组件来快速构建复杂的应用程序。 - RCP应用通常由多个插件组成,每个...
**GEF(Graphical Editing Framework)** 是一个用于构建图形编辑工具的开源框架,它为开发人员提供了一套全面的库和工具,用于创建基于Eclipse的富客户端平台(RCP)的应用程序,特别是那些涉及图形用户界面(GUI)...
5. **命令(Command)**:GEF使用命令模式来实现撤销/重做功能,每个编辑操作都对应一个命令对象。 6. **适配器(Adapter)**:提供了一种机制,使得不同组件之间可以相互通信,即使它们没有直接的依赖关系。 在...
通过阅读这两个API文档,开发者可以学习如何初始化和配置GEF编辑器,创建和操作EditParts,使用Draw2D进行图形绘制,以及如何结合RCP来构建一个完整的图形编辑应用。同时,文档还可能包含示例代码和常见问题解答,...
在本实例中,我们将探讨如何利用GEF实现一个简单的MVC(Model-View-Controller)架构,这是一种常见的软件设计模式,用于分离应用程序的数据、显示逻辑和用户交互。 1. **GEF框架基础**: - **模型(Model)**:...
- **GEF (Graphical Editing Framework)**:GEF是Eclipse平台提供的一个用于构建图形编辑器的框架,能够帮助开发者快速构建功能丰富的图形用户界面。适用于创建各种类型的图形编辑器,如流程图编辑器、UML建模工具等...