快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门威斯尼斯人娱乐平台_龟发之家论坛



在今朝的GEF版本(3.1M6)里,可用的LayoutManager还不是很多,在新闻组里常常会看到要求增添更多结构的帖子,有人也供给了自己的实现,例如这个GridLayout,相称于SWT中GridLayout的Draw2D实现,等等。虽然可以肯定GEF的未来版本里会增添更多的结构供开拓者应用(可能必要很长光阴),然而今朝要用GEF实现表格的操作还没有很直接的法子,这里说说我的做法,仅供参考。

实现表格的措施抉择于模型的设计,初看来我们彷佛应该有这些类:表格(Table)、行(Row)、列(Column)和单元格(Cell),每个模型工具对应一个EditPart,以及一个Figure,TablePart应该包孕RowPart和ColumnPart,问题是RowFigure和ColumnFigure会孕育发生交叉,想象一下你的表格该应用什么样的结构才能容纳它们?应用这样的模型并非不能实现(例如应用StackLayout),但我觉得这样的模型必要做的额外事情会很多,以是我应用基于列的模型。

在我的表格模型里,只有三种工具:Table、Column和Cell,但Column有一个子类HeaderColumn表示第一列,同时Cell有一个子类HeaderCell表示位于第一列里的单元格,后面这两个类的感化主如果模拟实现对行的操作--把对行的操作都转换为对HeaderCell的操作。例如,创建一个新行转换为在第一列中增添一个新的单元格,当然在这同时我们要让法度榜样给另外每一列同样增添一个单元格。

图1 表格编辑器

现在的问题便是如何让用户察觉不到我们是在对单元格而不是对行操作。必要改动的地方有这么几处:一是创建新行或改变行位置时显示与行宽同等的插入提示线,二是在用户点击位于第一列中的单元格(HeaderCell)时显示为全部行当选中,三是容许用户经由过程鼠标拖动改变行高度,着末是在改变行所在位置或大年夜小的时刻显斧精确的回显(Feedback)图形。下面依次先容它们的实现措施。

调剂插入线的宽度

在我们的调色板里有一个Row对象项,代表表格中的一个行,它的感化是创建新的行。留意这个对象项的名字虽然叫Row,实际上用它创建的是一个HeaderCell工具,创建它的代码如下:

tool = new CombinedTemplateCreationEntry("Row", "Create a new Row", HeaderCell.class, new SimpleFactory(HeaderCell.class), CbmPlugin.getImageDescriptor(IConstants.IMG_ROW), null);

创建新行的要领是从调色板里拖动它到想要的位置。在拖动历程中,跟着鼠标所在位置的变更,编辑器应该能显示一条直线,用来表示假云云时摊开鼠标新行将插入的位置。因为这个对象代表的是一个单元格,以是缺省环境下GEF会显示一条与单元格长度相同的插入线,为了让用户感到到是在插入行,我们必须改变插入线的宽度。详细的措施是在HeaderColumnPart的认真Layout的那个EditPolicy(承袭FlowLayoutEditPolicy)中覆盖showLayoutTargetFeedback()措施,改动后的代码如下:

protected void showLayoutTargetFeedback(Request request) {

super.showLayoutTargetFeedback(request);

// Expand feedback line's width

Diagram diagram = (Diagram) getHost().getParent().getModel();

Column column = (Column) getHost().getModel();

Point p2 = getLineFeedback().getPoints().getPoint(1);

p2.x = p2.x + (diagram.getColumns().size() - 1) * (column.getWidth() + IConstants.COLUMN_SPACING);

getLineFeedback().setPoint(p2, 1);

}

此中p2代表插入线中右边的那个点,我们将它的横坐标加上一个量即可增添这条线的长度,这个量和表格当前列的数目有关,和列间距也有关,谋略的措施看上面的代码很清楚。这样改动后的效果如下图所示,拖动行到新的位置时也会应用同样的插入线。

在getLocator()措施里,我们调用了HeaderCellPart的getRowBound()措施用于获得选中行的位置和尺寸,这个措施的代码如下(放在HeaderCellPart里是由于在Handle里经由过程getOwner()可以很轻易获得EditPart工具),行尺寸的谋略措施与前面插入线的环境类似:

public Rectangle getRowBound(){

Rectangle rect = getFigure().getBounds().getCopy();

Diagram diagram = (Diagram) getParent().getParent().getModel();

Column column = (Column) getParent().getModel();

rect.setSize(diagram.getColumns().size() * column.getWidth() + (diagram.getColumns().size() - 1) * IConstants.COLUMN_SPACING, rect.getSize().height);

return rect;

}

有了这个RowMoveHandle,只要把它代替原本缺省的MoveHandle加到HeaderColumnCell上即可,详细的措施便是覆盖DragRowEditPolicy的createSelectionHandles()措施,ResizableEditPolicy对这个措施的缺省实现是加一个黑框和八个节制点,而我们要改成下面这样:

protected List createSelectionHandles() {

List l = new ArrayList();

//四周的玄色边框

l澳门威斯尼斯人娱乐平台.add(new RowMoveHandle((GraphicalEditPart) getHost()));

//下方的节制点

l.add(new RowResizeHandle((GraphicalEditPart) getHost(), PositionConstants.SOUTH));

return l;

}

代码里用到的RowResizeHandle类是节制点的自定义实现,鄙人面很快会讲到。现在,用户可以看到全部行当选中的效果了。

这样,我们就把节制点拉成了节制线,由于它的位置与选择框(RowMoveHandle)的一部分重合,以是在界面上感到不到它澳门威斯尼斯人娱乐平台的澳门威斯尼斯人娱乐平台存在,但用户可以经由过程它节制行的高度,见下图。

图4 改变行高的提示

精确的回显图形

我们知道,在拖动图形和改变图形尺寸的时刻,GEF会显示一个"影图"(Ghost Shape)作为回显,也便是显示图形的新位置和尺寸信息。由于操作行时目标工具实际是单元格,以是在缺省环境下回显也是单元格的样子(宽度与列宽相同)。为此,在DragRowEditPolicy里要覆盖getInitialFeedbackBounds()措施,这个措施返回的Rectangle抉择了鼠标开始拖动时回显图形的初始状态,见以下代码:

protected Rectangle getInitialFeedbackBounds澳门威斯尼斯人娱乐平台() {

return ((HeaderCellPart) getHost()).getRowBound();

}

这时的回显见下图,在拖动行时也应用同样的回显。

图5 改变行高时的回显

颠末上面的改动,对HeaderCell的操作在界面上已经完全体现为对表格行的操作了。这些操作的结果会转换为一些Command,包括CreateHeaderCellCommand(创建新行,你也可以命名为CreateRowCommand)、MoveHeaderCellCommand(移动行)、DeleteHeaderCellCommand(删除行)和ChangeHeaderCellHeightCommand(改变行高)等,在这些类里要对所有列履行同样的操作(例如改变HeaderCell的高度的同时改变同一行中其他单元格的高度),这样在界面上才能维持表格的外不雅,具体的代码没有需要贴在这里了。

P.S.曾经斟酌过另一种实现表格的措施,便是模型里只有Table和Cell两种工具,然后自己写一个TableLayout认真单元格的结构。同样是由于改动的事情量比拟较较大年夜而没有采纳,由于那样的话行和列都要应用自定义要领处置惩罚,而这篇贴子先容的措施只关心行的处置惩罚就可以了。当然,这里说的也不是什么标准实现,不事效果照样不错的,而且确澳门威斯尼斯人娱乐平台凿可以实现,假如你有类似的需求可以作为参考。

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