您的位置:首页 > 其它

GEF 学习系列之三:缩放、位置和尺寸对齐

2010-04-23 17:00 190 查看
画布的缩放

由于Draw2D中的图形都具有天然的缩放功能,因此在GEF里实现缩放功能是很容易的,而且缩放的效果不错。GEF为我们提供了
ZoomInAction和ZoomOutAction以及对应的RetargetAction(ZoomInRetargetAction和
ZoomOutRetargetAction),只要在编辑器里构造它们的实例,然后在编辑器的ActionBarContributer类里将它们添加到想要的菜单或工具条位置即可。因为ZoomInAction和ZoomOutAction的构造方法要求一个ZoomManager类型的参数,而后者需要从GEF的RootEditPart中获得(ScalableRootEditPart或
ScalableFreeformRootEditPart),所以最好在编辑器的
configureGraphicalViewer()里构造这两个Action比较方便,请看下面的代码:

//获得ZoomManager
ZoomManager manager = rootEditPart.getZoomManager();
//放大比例数组
double[] zoomLevels = new double[]{
0.25,0.5,0.75,1.0,1.5,2.0,2.5,3.0,4.0,5.0,10.0,20.0
};
manager.setZoomLevels(zoomLevels);
//设置非百分比缩放
ArrayList<Object> zoomContributions = new ArrayList<Object>();
zoomContributions.add(ZoomManager.FIT_ALL);
zoomContributions.add(ZoomManager.FIT_HEIGHT);
zoomContributions.add(ZoomManager.FIT_WIDTH);
manager.setZoomLevelContributions(zoomContributions);
//注册放大Action
IAction action = new ZoomInAction(manager);
getActionRegistry().registerAction(action);
//注册缩小Action
action = new ZoomOutAction(manager);
getActionRegistry().registerAction(action);
//创建键盘句柄keyHander
KeyHandler keyHandler  = new KeyHandler();
keyHandler.put(KeyStroke.getPressed(SWT.DEL, 127, 0),
getActionRegistry().getAction(GEFActionConstants.DELETE));

keyHandler.put(KeyStroke.getPressed(SWT.F2, 0),
getActionRegistry().getAction(GEFActionConstants.DIRECT_EDIT));

//		getGraphicalViewer().setKeyHandler(keyHandler);
//可以用方向键来选择不同的图形
getGraphicalViewer().setKeyHandler(new GraphicalViewerKeyHandler(getGraphicalViewer()).setParent(keyHandler));


假设我们想把这两个命令添加到主工具条上,在ShapesEditorActionBarContributor里应该做两件事:在
buildActions()里构造对应的RetargetAction,然后在contributeToToolBar()里添加它们到工具条:

protected void buildActions() {
addRetargetAction(new DeleteRetargetAction());
addRetargetAction(new UndoRetargetAction());
addRetargetAction(new RedoRetargetAction());
//Retarget缩放Action
addRetargetAction(new ZoomInRetargetAction());
addRetargetAction(new ZoomOutRetargetAction());
//对齐方式
addRetargetAction(new AlignmentRetargetAction(PositionConstants.LEFT));
addRetargetAction(new AlignmentRetargetAction(PositionConstants.CENTER));
addRetargetAction(new AlignmentRetargetAction(PositionConstants.RIGHT));
addRetargetAction(new AlignmentRetargetAction(PositionConstants.TOP));
addRetargetAction(new AlignmentRetargetAction(PositionConstants.MIDDLE));
addRetargetAction(new AlignmentRetargetAction(PositionConstants.BOTTOM));
addRetargetAction(new MatchWidthRetargetAction());
addRetargetAction(new MatchHeightRetargetAction());
}
/**
* Add actions to the given toolbar.
* @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(org.eclipse.jface.action.IToolBarManager)
*/
public void contributeToToolBar(IToolBarManager toolBarManager) {
toolBarManager.add(getAction(ActionFactory.UNDO.getId()));
toolBarManager.add(getAction(ActionFactory.REDO.getId()));
toolBarManager.add(getAction(ActionFactory.DELETE.getId()));
toolBarManager.add(new Separator());
//水平方向对齐按钮
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_LEFT));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_CENTER));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_RIGHT));
toolBarManager.add(new Separator());
//垂直方向对齐按钮
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_TOP));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_MIDDLE));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ALIGN_BOTTOM));
//匹配宽度
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.MATCH_HEIGHT));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.MATCH_WIDTH));
//加上分割条
toolBarManager.add(new Separator());
//加上缩放按钮,注意这里的缩放Action的ID在GEF中已经定义了一些常数
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ZOOM_IN));
toolBarManager.add(getActionRegistry().getAction(GEFActionConstants.ZOOM_OUT));
//在工具栏上加上组合框
toolBarManager.add(new ZoomComboContributionItem(getPage()));
}


请注意,在contributeToToolBar()方法里我们额外添加了一个ZoomComboContributionItem
的实例,这个类也是GEF提供的,它的作用是显示一个缩放百分比的下拉框,用户可以选择或输入想要的数值。为了让这个下拉框能与编辑器联系在一起,我们要修改一下编辑器的getAdapter()方法,增加对它的支持:

public Object getAdapter(Class type) {
if(type == ZoomManager.class)
return((ScalableFreeformRootEditPart)getGraphicalViewer().getRootEditPart()).getZoomManager();
return super.getAdapter(type);
}


现在,打开编辑器后主工具条中将出现下图所示的两个按钮和一个下拉框:



有时候我们想让程序把用户当前的缩放值记录下来,以便下次打开时显示同样的比例。这就须要在画布模型里增加一个zoom变量,在编辑器的初始化过程中增加下面的语句,其中diagram是我们的画布实例:

ZoomManager manager
=
(ZoomManager)
getGraphicalViewer().getProperty(ZoomManager.class.toString());

if
(manager

!=

null
)

manager.setZoom(diagram.getZoom());

在保存模型前得到当前的缩放比例放在画布模型里一起保存:

ZoomManager manager
=
(ZoomManager)
getGraphicalViewer().getProperty(ZoomManager.class.toString());

if
(manager

!=

null
)

diagram.setZoom(manager.getZoom());

位置和尺寸对齐

图形编辑工具大多具有这样的功能:选中两个以上图形,再按一下按钮就可以让它们以某一个边或中心线对齐,或是调整它们为同样的宽度高度。GEF提供AlignmentAction和MatchSizeAction分别用来实现位置对齐和尺寸对齐,使用方法很简单,在编辑器的
createActions()方法里构造需要的对齐方式Action(例如对齐到上边、下边等等),然后在编辑器的
ActionBarContributor里通过这些Action对应的RetargetAction将它们添加到菜单或工具条即可。编辑器里的代码如下,注意最后一句的作用是把它们加到selectionAction列表里以响应选择事件:

IAction action
=
new
AlignmentAction((IWorkbenchPart)
this
,PositionConstants.LEFT);

getActionRegistry().registerAction(action);

getSelectionActions().add(action.getId());



AlignmentAction的构造方法的参数是编辑器本身和一个代表对齐方式的整数,后者可以是
PositionConstants.LEFT、CENTER、RIGHT、TOP、MIDDLE、BOTTOM中的一个;
MatchSizeAction有两个子类,MatchWidthAction和MatchHeightAction,你可以使用它们达到只调整宽度或高度的目的。下图是添加在工具条中的按钮,左边六个为位置对齐,最后两个为尺寸对齐,请注意,当选择多个图形时,被六个黑点包围的那个称为"主选择",对齐时以该图形所在位置和大小为准做调整。



图7 位置对齐和尺寸对齐
在实现位置对齐功能的时候发现一个问题,无论选择了几个图元,工具栏栏上的按钮都是显示灰色,最后有两个原因会导致出现这种现象:

Editor的createActions()里,是否getSelectionActions().add(action.getId()),其中action是AlignmentAction实例;

用于改变选中的图形元素尺寸的command(如ShapeSetConstraintCommand)的canExecute()方法是否支持RequestConstants.REQ_ALIGN_CHILDREN,或者如果想省事直接返回true即可;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: