3 系统实现
GEF基于MVC框架,可以方便地实现drop/drag、undo/redo、move、delete、resize等图形编辑器的基本功能,并且提供了常用的布局器,非常适合用于开发所见即所得的界面编辑器。其中,GEF的EditPart对应MVC中的Controller,Figure对应View。
本工具基于GEF开发,可以最大限度地减小开发工作量,增强软件的稳定性。同时,Java开发使得本工具可以在任何具有Java虚拟机的系统上运行,具有良好的跨平台性。
3.1 基于GEF实现的界面设计工具
本工具提供对菜单、状态条、位图,以及对话框控件(包括CheckBox, ComboBox,PushButton, RadioButton,MonthCalendar,GridView,M1Edit,ProgressBar,Property-Sheet,Static,StaticBox,TreeView,TrackBar,SpinBox等)的编辑功能。对于控件的修改,可以通过属性页和在界面上直接操作来进行。属性页上的编辑通过IPropertySource接口的setPropertyValue方法告知Model,Model再通过PropertyChangeSupport类的firePropertyChange方法通知EditPart做出修改;来自界面上的变化被封装成request派发给EditPart,EditPart再通过command修改Model中的数据,Model在修改完数据之后告知EditPart有数据被修改;EditPart收到Property改变的通知后,根据修改数据类型做出相应操作(比如重绘figure等)。以对CheekBox的操作为例来说明基于GEF的控件处理流程,如图4所示。其中,操作A是从工具箱拖拽一个新的CheckBox到Dialog中;操作B是通过属性页修改CheckBox显示的文本(Text);操作C直接通过选中CheckBox拖拽改变其大小。操作A1~A4、B1~B3、C1~C3为具体的执行流程。
3.2 图形显示问题
在GEF中,每个视图只有在其父视图的有效范围内才能响应交互事件。如果直接按照MiniGUI的控件关系来组织模型,则界面设计工具不能很好地完成与用户的交互。
以菜单为例,生成MiniGUI中菜单部分的代码仅需完成一棵树的遍历。这棵树的每个非叶节点都是一个弹出菜单,叶节点是普通的菜单项,根节点是一个虚节点,用于串连起整个菜单,如图5(a)所示。每个节点都被称作MenuItem。这种树形结构在GEF显示时根据Model创建的Figure如图5(b)所示,其中Figure11为Figure1的childFigure。在GEF中,只有childFigure被包含在parentFigure的有效范围内,对childFigure提出的请求才能被其parentFigure派发给childFigure对应的control-ler,并反映给Model,如图5(c)所示。显然树形结构无法满足修改菜单项的需求,因此,在MenuItem构成的树形结构基础上增加了由MeInu组成的链表结构,同时每个MenuItem都增加一个指向自己上一级MenuItem的Par-ent指针,如图5(d)所示。每个Menu(ij)记录包括的所有MenuItem(ij,k),以及创建自己的Menultem(i,j)。MenuItem(ij,k)表示属于Menu(ij)的第k个MenuItem,Menu(ij)表示MenuItem(i,j)展开的下级Menu。所有的Menu组成一个链表,GEF显示的是这个链表的内容,而不是原来的MenuItem树。这样,每个MenuItem对应的Figure就可以包含在其parentFigure中,相应的controller也就能够收到界面上传来的请求。
将MenuItem属性改变为PopUp,可以为其建立下级子Menu。新建函数的流程如下(参数是当前属性修改为PopUp的MenuItem):
为Menu新建一个MenuItem的函数: