快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

金沙国际娱城app_酒文化网进入



虽然很多GEF利用法度榜样里都邑用到连接(Connection),但也有一些利用是不必要用连接来表达关系的,我们今朝正在做的这个项目便是这样一个例子。在这类利用中,模型工具间的关系主要经由过程图形的包孕来表达,以是大年夜多是一对多关系。

图1 不应用连接的GEF利用

先简单描述一下我们这个项目,该项目必要一个图形化的模型编辑器,主要功能是在一个具有三行N列的表格中自由增添/删除节点,节点可在不合单元格间拖动,可以合并金沙国际娱城app相邻节点,表格列可增减、拖动等等。因为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

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

图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两种环境可以统一处置惩罚,这个金沙国际娱城apptransposer只在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

上面这些语句的感化是将父图形的高(宽)度匀称分配给每个子图形,假如是处于着末的一位的子图形,让它盘踞所有剩下的空间(防止除不尽的环境留下空缺)。完成了这个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,由于在需求中,用户向单元格里添加第一个节点时,该节点要充溢单元格;当单元格里有两个节点时,每个节点占二分之一的高度;依次类推。下面的表格总结了各个图形应用的结构治理。由表可见,只有包孕子图形的那些图形才必要结构治理器,缘故原由很显着:结构治理器关心金沙国际娱城app和治理的是"子"图形,请时候切记这一点。

结构治理器

直接子图形

画布

ToolbarLayout

ColumnLayout

列头部、列下部

-列头部

-列下部

FillLayout

单元格

单元格

FillLayout

节点

节点

这里必要分外提醒一点:在一个图形应用ToolbarLayout或子类作为结构治理器时,图形对应的EditPart上假如安装了FlowLayoutEditPolicy或子类,你可能会获得一个ClassCastException非常。例如例子中的CellFigure,它对应的EditPart是CellPart,其上安装了CellLayoutEditPolicy是FlowLayoutEditPolicy的一个子类。呈现这个非常的缘故原由是在FlowLayoutEditPolicy的isHorizontal()措施中会将图形的layout强制转换为FlowLayout,而我们应用的是ToolbarLayout。我觉得这是GEF的一个纰金沙国际娱城app漏,由于作者曾说过FlowLayout可利用于ToolbarLayout。幸好办理措施也不繁杂:在你的那个EditPolicy中覆盖isHorizontal()措施,在这个措施里先判断layout是ToolbarLayout照样FlowLayout,再根据结果返回相宜的boolean值即可。

着末,关于我们的画布还有一个问题没有办理,我们盼望表格列增多到必然程度后,画布可以向右边扩展尺寸,前面说过画布应用的是FreeformLayer作为图形。为了达到目的,还必须在editor里设置rootEditPart为ScalableRootEditPart,要留意不是ScalableFreeformRootEditPart,后者在必要各个偏向都能扩展的画布的利用法度榜样中常常被应用。关于各类RootEditPart的用法,在后续帖子里将会先容到。

以上结合详细实例解说了若何在GEF中应用ToolbarLayout以及自定义简单的结构治理器。我们构造图形应该遵守一个原则,那便是只管即便让结构治理器抉择每个子图形的位置和尺寸,这样可以避免很多麻烦。当然也有例外,比如在XYLayout这种只关心子图形金沙国际娱城app位置的结构治理器中,就必须为每个子图形指定尺寸,否则图形将由于尺寸过小而弗成见,这也是一个开拓职员十分轻易纰漏的地方。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: