[GEF]在非XYLayout布局的container里调整children尺寸

以前只做过两种类型的GEF程序,一种是画布使用XYLayout,子图形可以在上面随意改变大小和位置;另一种是画布使用非XYLayout的布局,子图形的大小和位置由布局决定,用户不能用鼠标拖动的方式改变。现在这个项目有点特殊,因为要实现类似“表格”的功能,所以要求画布使用ToolbarLayout排列表格列,但列的高度要能够改变。我查看了FlowLayoutEditPolicy类,里面没有一个类似“createChangeConstraintCommand”这样的方法,那么该怎样实现这个功能呢?

resize-column.gif
图1 画布使用ToolbarLayout同时可以调整列的高度

经过黄老大的指点和查看代码,原来要在画布的EditPolicy里覆盖createChildEditPolicy()方法,FlowLayoutEditPolicy缺省是返回一个NonResizableEditPolicy,我们要改为返回一个ResizableEditPolicy,为了只让用户能拖动列的底部,还要稍微设置一下这个EditPolicy,如下所示:

protected EditPolicy createChildEditPolicy(EditPart child) {
    ResizableEditPolicy policy 
= new ResizableEditPolicy();
    policy.setResizeDirections(PositionConstants.SOUTH);
    
return policy;
}

在运行时,这个被返回的EditPolicy会被安装在child的EditPart上,把我们的画布看作parent,列就是child。当用户拖动列图形的handler时,产生一个类型为REQ_RESIZE的请求,这个请求被转发给parent的EditPolicy,所以我们要在画布的EditPolicy里覆盖getCommand()方法对这个请求进行处理,如下所示:

public Command getCommand(Request request) {
    
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已经考虑到了这种情况。

posted @ 2005-03-29 17:59  八进制  阅读(...)  评论(... 编辑 收藏