目标:1. 创建大纲视图(Outline)
2. 实现鹰眼视图
创建大纲视图(Outline):
在Eclipse中创建大纲视图需要创建IContentOutlinePage接口的实现类,并且在Editor的getAdapter方法中返回实现类的实例。
public Object getAdapter(Class type) {
if (type == IContentOutlinePage.class) {
return new MyContentOutlinePage();
}
}
普通插件项目一般直接继承org.eclipse.ui.views.contentoutline.ContentOutlinePage,而在GEF项目中一般使用org.eclipse.gef.ui.parts.ContentOutlinePage(拥有一个EditPartViewer)。
class MyContentOutlinePage extends org.eclipse.gef.ui.parts.ContentOutlinePage
我们通过MyContentOutlinePage 的构造函数传入一个TreeViewer实例给这个page
public MyContentOutlinePage() {
super(new TreeViewer());
}
回忆一下,GEF的EditPartViewer分为两大类,GraphicalViewer和TreeViewer。前面几回使用的都是GraphicalViewer,而TreeViewer一般用来实现Outline。
使用TreeViewer和使用GraphicalViewer的方法有一定的相似性。
1. 它们都需要定义EditParts。使用TreeViewer需要提供实现了TreeEditPart接口的EditParts,GEF提供了AbstractTreeEditPart方便用户使用,AbstractTreeEditPart拥有一个Widget引用,代表一个Tree或TreeItem。
因为我们打算在Outline上显示HelloModel,所以我们要创建ContentsTreeEditPart和HelloTreeEditPart。
2. 它们都需要一个工厂类把模型和控制器联系起来。
3. 它们的配置有极大的相似性。在第一篇自学笔记中归纳过GraphicalEditor为什么需要EditDomain(第4点)以及如何配置GraphicalViewer(见最后一段),TreeViewer的配置与之极为相似。
getViewer().createControl(sash); //创建默认控件(Tree)。亦可自定义控件并调用setControl设置控件。
getViewer().setEditDomain(getEditDomain());//使用与Editor相同的EditDomain以便共享CommandStack,保持Redo/Undo的一致性。
getViewer().setEditPartFactory(new TreeEditPartFactory());
getViewer().setContents(contents);
getSelectionSynchronizer().addViewer(getViewer());
如果要在大纲中操作图形模型,需要在EditParts中安装EditPolicies。其中TreeContainerEditPolicy是专门针对TreeViewer的EditPolicy。
运行时,发现删除HelloModel之后再undo,Outline中模型的顺序可能会改变。这是由于DeleteCommand只是简单的把HelloModel从ContentsModel中移除(redo)或增加到列表尾部(redo)。改进的话可以排序,或者记住删除对象在列表中的位置。
实现鹰眼功能:
Copy就好!
Canvas canvas = new Canvas(sash, SWT.BORDER);
LightweightSystem lws = new LightweightSystem(canvas);
ScrollableThumbnail thumbnail = new ScrollableThumbnail((Viewport) ((ScalableRootEditPart) getGraphicalViewer().getRootEditPart()).getFigure());
thumbnail.setSource(((ScalableRootEditPart) getGraphicalViewer().getRootEditPart()).getLayer(LayerConstants.PRINTABLE_LAYERS));
lws.setContents(thumbnail);