[GEF]在非XYLayout布局的container里调整children尺寸
以前只做过两种类型的GEF程序,一种是画布使用XYLayout,子图形可以在上面随意改变大小和位置;另一种是画布使用非XYLayout的布局,子图形的大小和位置由布局决定,用户不能用鼠标拖动的方式改变。现在这个项目有点特殊,因为要实现类似“表格”的功能,所以要求画布使用ToolbarLayout排列表格列,但列的高度要能够改变。我查看了FlowLayoutEditPolicy类,里面没有一个类似“createChangeConstraintCommand”这样的方法,那么该怎样实现这个功能呢?
图1 画布使用ToolbarLayout同时可以调整列的高度
经过黄老大的指点和查看代码,原来要在画布的EditPolicy里覆盖createChildEditPolicy()方法,FlowLayoutEditPolicy缺省是返回一个NonResizableEditPolicy,我们要改为返回一个ResizableEditPolicy,为了只让用户能拖动列的底部,还要稍微设置一下这个EditPolicy,如下所示:
ResizableEditPolicy policy = new ResizableEditPolicy();
policy.setResizeDirections(PositionConstants.SOUTH);
return policy;
}
在运行时,这个被返回的EditPolicy会被安装在child的EditPart上,把我们的画布看作parent,列就是child。当用户拖动列图形的handler时,产生一个类型为REQ_RESIZE的请求,这个请求被转发给parent的EditPolicy,所以我们要在画布的EditPolicy里覆盖getCommand()方法对这个请求进行处理,如下所示:
if (REQ_RESIZE_CHILDREN.equals(request.getType())) {
ChangeColumnHeightCommand cmd = new ChangeColumnHeightCommand();
Column column = (Column) ((ColumnPart) ((ChangeBoundsRequest) request).getEditParts().get(0)).getModel();
cmd.setColumn(column);
cmd.setNewHeight(column.getHeight() + ((ChangeBoundsRequest) request).getSizeDelta().height);
return cmd;
}
return super.getCommand(request);
}
这就会返回一个用来调整列高度的Command,这个命令的具体内容这里不赘述了。createChildEditPolicy是在LayoutEditPolicy里定义的一个抽象方法,GEF提供的与Layout有关的EditPolicy里都会提供一个缺省的实现,但在需求比较特殊的情况下我们要提供自己的实现。这里是OrderedLayoutEditPolicy(FlowLayoutEditPolicy的父类)关于该方法的注释:“Since Ordered layouts generally don't use constraints, a NonResizableEditPolicy is used by default for children. Subclasses may override this method to supply a different EditPolicy.”很明显GEF已经考虑到了这种情况。