GEF入门系列(五、浅谈布局)

gef快速入门教程(详细文档,里面有完整例子) gef快速入门教程 一份文档,让你能对gmf快速入门,且能做出属于自己的文档 立即下载

虽然很多GEF应用程序里都会用到连接(Connection),但也有一些应用是不需要用连接来表达关系的,我们目前正在做的这个项目就是这样一个例子。在这类应用中,模型对象间的关系主要通过图形的包含来表达,所以大多是一对多关系。

cbm1.gif
图1 不使用连接的GEF应用

先简单描述一下我们这个项目,该项目需要一个图形化的模型编辑器,主要功能是在一个具有三行N列的表格中自由增加/删除节点,节点可在不同单元格间拖动,可以合并相邻节点,表格列可增减、拖动等等。由于SWT/Jface提供的表格很难实现这些功能,所以我们选择了使用GEF开发,目前看来效果还是很不错的(见下图),这里就简单介绍一下实现过程中与图形和布局有关的一些问题。

在动手之前首先还是要考虑模型的构造。由于Draw2D只提供了很有限的Layout,如ToolbarLayout、FlowLayout和XYLayout,并没有一个GridLayout,所以不能把整个表格作为一个EditPart,而应该把每一列看作一个EditPart(因为对列的操作比对行的操作多,所以不把行作为EditPart),这样才能实现列的拖动。另外,从需求中可以看出,每个节点都包含在一个列中,但仔细再研究一下会发现,实际上节点并非直接包含在列中,而是有一个单元格对象作为中间的桥梁,即每个列包含固定的三个单元格,每个单元格可以包含任意个节点。经过以上分析,我们的模型、EditPart和Figure应该已经初步成形了,见下表:

 

模型

EditPart

Figure

画布

Diagram

DiagramPart

FreeformLayer

列

Column

ColumnPart

ColumnFigure

单元格

Cell

CellPart

CellFigure

节点

Node

NodePart

NodeFigure

表中从上到下是包含关系,也就是一对多关系,下图简单显示了这些关系:

cbm2.gif
图2 图形包含关系图

让我们从画布开始考虑。在画布上,列显示为一个纵向(高大于宽)的矩形,每个列有一个头(Header)用来显示列名,所有列在画布上是横向排列的。因此,画布应该使用ToolbarLayout或FlowLayout中的一种。这两种Layout有很多相似之处,尤其它们都是按指定的方向排列显示图形,不同之处主要在于:当图形太多容纳不下的时候,ToolbarLayout会牺牲一些图形来保持一行(列),而FlowLayout则允许换行(列)显示。

对于我们的画布来说,显然应该使用ToolbarLayout作为布局管理器,因为它的子图形ColumnFigure是不应该出现换行的。以下是定义画布图形的代码:

Figure f = new FreeformLayer();
ToolbarLayout layout
=new ToolbarLayout();
layout.setVertical(
false);
layout.setSpacing(
5);
layout.setStretchMinorAxis(
true);
f.setLayoutManager(layout);
f.setBorder(
new MarginBorder(5));

其中setVertical(false)指定横向排列子图形,setSpacing(5)指定子图形之间保留5象素的距离,setStretchMinorAxis(true) 指定每个子图形的高度都保持一致。

ColumnFigure的情况要稍微复杂一些,因为它要有一个头部区域,而且它的三个子图形(CellFigure)合在一起要能够充满下部区域,并且适应其高度的变化。一开始我用Draw2D提供的Label来实现列头,但有一个不足,那就是你无法设置它的高度,因为Label类覆盖了Figure的getPreferedSize()方法,使得它的高度只与里面的文本有关。解决方法是构造一个HeaderFigure,让它维护一个Label,设置列头高度时实际设置的是HeaderFigure的高度;或者直接让HeaderFiguer继承Label并重新覆盖getPreferedSize()也可以。我在项目里使用的是前者。

第二个问题花了我一些时间才搞定,一开始我是在CellPart的refreshVisuals()方法里手动设置CellFigure的高度为ColumnFigure下部区域高度的三分之一,但这样很勉强,而且还需要额外考虑spacing带来的影响。后来通过自定义Layout的方式比较圆满的解决了这个问题,我让ColumnFigure使用自定义的ColumnLayout,这个Layout继承自ToolbarLayout,但覆盖了layout()方法,内容如下:

class ColumnLayout extends ToolbarLayout {
    public 
void layout(IFigure parent) {
        IFigure nameFigure
=(IFigure)parent.getChildren().get(0);
        IFigure childrenFigure
=(IFigure)parent.getChildren().get(1);
        Rectangle clientArea
=parent.getClientArea();
        nameFigure.setBounds(
new Rectangle(clientArea.x,clientArea.y,clientArea.width,30));
        childrenFigure.setBounds(
new Rectangle(clientArea.x,nameFigure.getBounds().height+clientArea.y,clientArea.width,clientArea.height-nameFigure.getBounds().height));
    }
}

也就是说,在layout里控制列头和下部的高度分别为30和剩下的高度。但这还没有完,为了让单元格正确的定位在表格列中,我们还要指定列下部图形(childrenFigure)的布局管理器,因为实际上单元格都是放在这个图形里的。前面说过,Draw2D并没有提供一个像SWT中FillLayout那样的布局管理器,所以我们要再自定义另一个layout,我暂时给它起名为FillLayout(与SWT的FillLayout同名),还是要覆盖layout方法,如下所示(因为用了transposer所以horizontal和vertical两种情况可以统一处理,这个transposer只在horizontal时才起作用):

public void layout(IFigure parent) {
    List children 
= parent.getChildren();
    
int numChildren = children.size();
    Rectangle clientArea 
= transposer.t(parent.getClientArea());
    
int x = clientArea.x;
    
int y = clientArea.y;
    
for (int i = 0; i < numChildren; i++) {
        IFigure child 
= (IFigure) children.get(i);
        Rectangle newBounds 
= new Rectangle(x, y, clientArea.width, -1);

        
int divided = (clientArea.height - ((numChildren - 1) * spacing)) / numChildren;
        
if (i == numChildren - 1)
            divided 
= clientArea.height - ((divided + spacing) * (numChildren - 1));
        newBounds.height 
= divided;
        child.setBounds(transposer.t(newBounds));
        y 
+= newBounds.height + spacing;
    }
}

上面这些语句的作用是将父图形的高(宽)度平均分配给每个子图形,如果是处于最后的一位的子图形,让它占据所有剩下的空间(防止除不尽的情况留下空白)。完成了这个FillLayout,只要让childrenFigure使用它作为布局管理器即可,下面是ColumnFigure的大部分代码,列头图形(HeaderFigure)和列下部图形(ChildrenFigure)作为内部类存在:

private HeaderFigure name = new HeaderFigure();
private ChildrenFigure childrenFigure 
= new ChildrenFigure();
public ColumnFigure() {
    ToolbarLayout layout 
= new ColumnLayout();
    layout.setVertical(
true);
    layout.setStretchMinorAxis(
true);
    setLayoutManager(layout);
    setBorder(
new LineBorder());
    setBackgroundColor(color);
    setOpaque(
true);
    add(name);
    add(childrenFigure);
    setPreferredSize(
100, -1);
}
class ChildrenFigure extends Figure {
    public ChildrenFigure() {
        ToolbarLayout layout 
= new FillLayout();
        layout.setMinorAlignment(ToolbarLayout.ALIGN_CENTER);
        layout.setStretchMinorAxis(
true);
        layout.setVertical(
true);
        layout.setSpacing(
5);
        setLayoutManager(layout);
    }
}
class HeaderFigure extends Figure {
    private String text;
    private Label label;
    public HeaderFigure() {
        
this.label = new Label();
        
this.add(label);
        setOpaque(
true);
    }
    public String getText() {
        
return this.label.getText();
    }
    public Rectangle getTextBounds() {
        
return this.label.getTextBounds();
    }
    public 
void setText(String text) {
        
this.text = text;
        
this.label.setText(text);
        
this.repaint();
    }
    public 
void setBounds(Rectangle rect) {
        super.setBounds(rect);
        
this.label.setBounds(rect);
    }
}

单元格的布局管理器同样使用FillLayout,因为在需求中,用户向单元格里添加第一个节点时,该节点要充满单元格;当单元格里有两个节点时,每个节点占二分之一的高度;依次类推。下面的表格总结了各个图形使用的布局管理。由表可见,只有包含子图形的那些图形才需要布局管理器,原因很明显:布局管理器关心和管理的是"子"图形,请时刻牢记这一点。

 

布局管理器

直接子图形

画布

ToolbarLayout

列

列

ColumnLayout

列头部、列下部

-列头部

无

无

-列下部

FillLayout

单元格

单元格

FillLayout

节点

节点

无

无

这里需要特别提醒一点:在一个图形使用ToolbarLayout或子类作为布局管理器时,图形对应的EditPart上如果安装了FlowLayoutEditPolicy或子类,你可能会得到一个ClassCastException异常。例如例子中的CellFigure,它对应的EditPart是CellPart,其上安装了CellLayoutEditPolicy是FlowLayoutEditPolicy的一个子类。出现这个异常的原因是在FlowLayoutEditPolicy的isHorizontal()方法中会将图形的layout强制转换为FlowLayout,而我们使用的是ToolbarLayout。我认为这是GEF的一个疏忽,因为作者曾说过FlowLayout可应用于ToolbarLayout。幸好解决方法也不复杂:在你的那个EditPolicy中覆盖isHorizontal()方法,在这个方法里先判断layout是ToolbarLayout还是FlowLayout,再根据结果返回合适的boolean值即可。

最后,关于我们的画布还有一个问题没有解决,我们希望表格列增多到一定程度后,画布可以向右边扩展尺寸,前面说过画布使用的是FreeformLayer作为图形。为了达到目的,还必须在editor里设置rootEditPart为ScalableRootEditPart,要注意不是ScalableFreeformRootEditPart,后者在需要各个方向都能扩展的画布的应用程序中经常被使用。关于各种RootEditPart的用法,在后续帖子里将会介绍到。

以上结合具体实例讲解了如何在GEF中使用ToolbarLayout以及自定义简单的布局管理器。我们构造图形应该遵守一个原则,那就是尽量让布局管理器决定每个子图形的位置和尺寸,这样可以避免很多麻烦。当然也有例外,比如在XYLayout这种只关心子图形位置的布局管理器中,就必须为每个子图形指定尺寸,否则图形将因为尺寸过小而不可见,这也是一个开发人员十分容易疏忽的地方。

Eclipse插件开发:GEF入门系列宝典_gef_ 由于工作的需要,最近开始研究GEF(Graphical Editor Framework)这个框架,它可以用来给用户提供图形化编辑模型的功能,从而提升用户体验,典型的应用如图形化的流程设计器、UML类图编辑器等等。 立即下载

相关推荐

12V转5V稳压电路详细分析(7805三端稳压,LM2596稳压)

7805线性三端稳压 DCDC的意思是直流变到直流(不同直流电源值的转换),只要符合这个定义都可以叫DCDC转换器,或称之为开关电源或开关调整器。 7805属于常用的线性三端稳压器,输入电压范围不大于35V,输入输出压差2V,最大输出电流1.5A,下图为原理图,其原理简单,使 用方便,深受很多用户的喜爱。但是其不足之处就是效率低,特别是压差越大时其效率越低。比如这里12V转5V的效率为 5V/12V≈41.7%。 如上电路是最经典的7805稳压5V电路,电路中有两个电容,电容的作用如下: ...

a2001444的博客 9万+

[Eclipse]GEF入门系列(五、浅谈布局)

虽然很多GEF应用程序里都会用到连接(Connection),但也有一些应用是不需要用连接来表达关系的,我们目前正在做的这个项目就是这样一个例子。在这类应用中,模型对象间的关系主要通过图形的包含来表达,所以大多是一对多关系。 图1 不使用连接的GEF应用 先简单描述一下我们这个项目,该项目需要一个图形化的模型编辑器,主要功能是在一个具有三行N列的表格中自由增加/删除节点,节点可在不同...

diaozhuo4700的博客 296

电子技术设计——16×16点阵汉字显示设计

同时,设计还应注重提升显示品质,以保证汉字的稳定展示和观感舒适。本设计的目的是构建一个能够准确在LED点阵上展示汉字的系统,并允许用户通过输入设备来选择所需的汉字,我们将验证设计方案的实际操作性和效果,以确保其满足设计目标。在LED点阵显示和汉字信息处理技术的结合下,研究者们着手研究如何在LED点阵上有效地显示汉字,并提出了一系列显示算法和优化策略,旨在实现清晰且易于阅读的汉字显示效果。首先,你需要准备16×16的LED点阵面板,通常这些点阵是8×8点阵的两倍,因此可以由两个8×8的点阵组合而成。

weixin_68094467的博客 1533

[Eclipse]GEF入门系列(四、其他功能)

最近由于实验室任务繁重,一直没有继续研究GEF,本来已经掌握的一些东西好象又丢掉了不少,真是无奈啊,看来还是要经常碰碰。刚刚接触GEF的朋友大都会有这样的印象:GEF里概念太多,比较绕,一些能直接实现的功能非要拐几个弯到另一个类里做,而且很多类的名字十分相似,加上不知道他们的作用,感觉就好象一团乱麻。我觉得这种情况是由图形用户界面(GUI)的复杂性所决定的,GUI看似简单,实际上包含了相...

diaozhuo4700的博客 305

抖音视频数据抓取

最近经常有人问我抓取抖音视频的数据,问我一些很小白的问题,算法给他也不会用。 还是先抓包,获取需要的接口和参数,相关的算法在其它文章里面有描述。 搜索个视频看看 查看抓的包信息: 可以看到,这里是post请求...

2501_91048859的博客 3100

Oracle-如何修复undo坏快

undo出现坏快,导致数据库宕机,无法启动

qqqyyy0422的博客 571

使用图形编辑框架GEF创建基于Eclipse的应用程序

简介: 了解使用图形编辑框架(Graphical Editing Framework,GEF)创建基于 Eclipse 的应用程序涉及的最初步骤。此外,介绍了目前在 Eclipse 中引导创建图形编辑器过程使用的选项。 本文将介绍使用图形编辑框架(Graphical Editing Framework,GEF)的步骤。我们不是完整地完成每个步骤,而是将使用您的应用程序模型的子集,并先使该

wwj13141988的专栏 2915

软硬件融合加速技术系列文章

目录 文章目录目录计算机组成原理Linux 操作系统原理处理器进程管理内存管理I/O 系统文件系统网络协议栈资源管理设备管理GPUFPGASmartNIC/DPU 计算机组成原理 《计算机组成原理 — 冯诺依曼体系结构》 《计算机组成原理 — 基本硬件设备》 《计算机组成原理 — CPU 中央处理器》 《计算机组成原理 — 指令系统》 《计算机组成原理 — 总线系统》 《计算机组成原理 — 存储系统》 《计算机组成原理 — 输入输出系统 — 存储控制器接口类型》 《计算机组成原理 — 服务器》 《计算机组成

烟云的计算 6808

Eclipse GEF Classic 项目教程

Eclipse GEF Classic 项目教程 1. 项目的目录结构及介绍 Eclipse GEF Classic 项目的目录结构如下: gef-classic/ ├── CONTRIBUTING.md ├── README.md ├── gef/ │ ├── draw2d/ │ ├── mvc/ │ ├── zest/ │ └── ... ├── .gitignore ├── ...

gitblog_01109的博客 479

你以为你懂 Java 反射?看了这篇源码分析,我发现我以前都错了

摘要:本文讲述了一次生产环境Metaspace内存溢出的故障排查经历。事故源于一个通用数据导出功能中频繁使用反射调用method.invoke(),触发了JVM的"膨胀机制":当同一Method对象调用超过15次时,JVM会动态生成GeneratedMethodAccessor类,导致Metaspace被撑爆。文章分析了问题根源在于循环中反复调用getMethods()创建新Method对象,并提出了三种解决方案:缓存Method对象、改用MapStruct/MethodHandle工具

BUG猿的博客 770

诊断CAPL自动化(3)——封装了接收诊断数据的通用CAPL脚本函数库

DiagGetRespPrimitiveSize (获取诊断响应的单个数据) diagGetPrimitiveData (获取诊断返回的所有数据) DiagGetRespParameter(数值类型) DiagGetRespParameter(字符串类型) DiagGetRespParameter(byte数组)

蚂蚁小兵 6222

[Eclipse]GEF入门系列(十二、自定义Request)

先简单回顾一下Request在GEF里的作用。Request是GEF里一个比较重要的角色,Tool将原始的鼠标事件转换为EditPart可以识别的请求,Request则承载了这些请求信息。举例来说,用户在调色板(Palette)里选择了创建节点工具(CreationTool),然后在画布区域按下鼠标左键,这时产生在画布上的鼠标单击事件将被CreationTool转换为一个CreateRe...

diaozhuo4700的博客 199

Python实战:打造学生信息管理系统

通过本教程,我们构建了一个简单的学生信息管理系统,实现了基本的添加、删除、修改和查询功能。当然,这个系统还有很多可以改进和扩展的地方,比如添加用户界面、增加数据持久化功能、支持批量操作等。简介:本文将介绍如何使用Python编写一个功能齐全的学生信息管理系统,包括添加、删除、修改和查询学生信息的基本操作。学生信息管理系统是学校日常管理中不可或缺的一部分,它能够帮助管理人员快速、准确地管理学生信息,提高工作效率。为了实现上述功能,我们可以设计一个包含学生信息的字典,并使用函数来封装各个操作。

铭渊老黄 1492

GEF:应用示例列表

简单的节点连线(应用实例) 隔间形状(用GMF生成简化的数据库设计器) 不使用连接的GEF应用(浅谈布局) 表格的一个实现 树的一个实现 容器应用(XYLayout和展开/折叠功能)          推荐:你可能需要的在线电子书   欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]...

weixin_34232363的博客 239

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【亲测免费】 Eclipse GEF Classic 使用教程

Eclipse GEF Classic 使用教程 项目介绍 Eclipse GEF (Graphical Editing Framework) Classic 是一个开源项目,旨在为开发者提供一个强大的图形编辑框架。GEF Classic 是 Eclipse 生态系统的一部分,支持 MVC 架构,并且与 Draw2d 和 Zest 等组件紧密集成。该项目欢迎社区贡献,并且是成熟稳定的项目之一。 项...

gitblog_00041的博客 694

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

GEF 入门教程

GEF教程.pdf+git项目源码 希望可以帮助入门学习GEF的人

Runner_up的博客 2218

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

[Eclipse]GEF入门系列(一、Draw2D)

鸡年第一天,首先向大家拜个年——恭祝新春快乐,万事如意。一年之计在于春,你对新的一年有什么安排呢?好的,下面还是进入正题吧。 关于Java2D相信大家都不会陌生,它是基于AWT/Swing的二维图形处理包, JDK附带的示例程序向我们展示了Java2D十分强大的图形处理能力。在Draw2D出现以前,SWT应用程序在这方面一直处于下风,而Draw2D这个SWT世界里的Java2D改变了这...

diaozhuo4700的博客 478

[Eclipse]GEF入门系列(三、应用实例)

构造一个GEF应用程序通常分为这么几个步骤:设计模型、设计EditPart和Figure、设计EditPolicy和Command,其中 EditPart是最主要的一部分,因为在实现它的时候不可避免的要使用到EditPolicy,而后者又涉及到Command。 现在我们来看个例子,它的功能非常简单,用户可以在画布上增加节点(Node)和节点间的连接,可以直接编辑节点的名称以及改变节点的...

diaozhuo4700的博客 375

探索Eclipse Graphical Editing Framework(GEF):构建图形化应用的新时代

探索Eclipse Graphical Editing Framework(GEF):构建图形化应用的新时代 项目地址:https://gitcode.com/gh_mirrors/ge/gef 1、项目介绍 Eclipse Graphical Editing Framework (GEF) 是一个强大的工具包,专为在Eclipse环境中集成和创建图形化应用程序而设计。它提供了一系列组件,包括[D...

gitblog_00092的博客 893
上一篇: GEF入门系列(四、其他功能)
下一篇: GEF入门系列(六、添加菜单和工具条)
kernel_engine
博客等级 码龄22年 6粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值