创建一个RCP项目org.tutorial.step,插件依赖关系加上 org.eclipse.gef。
创建一个Editor,其实现类为DiagramEditor,继承自GraphicalEditor。
Editor系列类的继承关系如下:
org.eclipse.ui.part.WorkbenchPart 所有workbench part的抽象基类,包含ViewPart和EditorPart。
-org.eclipse.ui.part.EditorPart 所有workbench editor的抽象基类,Eclipse项目中的Editor都派生于它。
–org.eclipse.gef.ui.parts.GraphicalEditor GEF提供的editor的抽象基类,它包含一个GraphicalViewer控件。
—org.eclipse.gef.ui.parts.GraphicalEditorWithPalette 提供带Palette的Editor,它包含一个PaletteViewer控件和一个GraphicalViewer控件。
—org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette 提供的是flyout palette。
注:根据javadoc描述,GraphicalEditor与GraphicalEditorWithFlyoutPalette这两个类的实现方式并没有最终确定下来,如果要用的话,可以copy它们的实现方式。所以我在org.tutorial.step.ui包下创建了一个GraphicalEditor类,内容完全拷贝自org.eclipse.gef.ui.parts.GraphicalEditor(项目需要增加插件依赖org.eclipse.ui.views),并使DiagramEditor继承自这个新的GraphicalEditor类。今后可以自由更改这个基类,也防止Eclipse突然修改这个基类的实现。加个菜单用来打开空的GEF Editor。
定义一个DiagramAction,继承自org.eclipse.jface.action.Action。实现run方法。
通过修改ApplicationActionBarAdvisor类来定义菜单。修改DiagramEditor的构造函数,加上setEditDomain(new DefaultEditDomain(this));
Edit domain管理命令堆栈(command stack)、工具条(palette viewer)等。Edit domain还起通知在Graphical viewer中生成的SWT事件的作用。因此,一定要建立一个Edit domain。
当我们把Graphical viewer放在Editor中时,我们使用DefaultEditDomain(比如本例)。如果把Graphical viewer放在View中或者stand-alone application中时,要用org.eclipse.gef.EditDomain。- 接下来就要按照GEF的套路分别创建模型、控制器和视图了。第一步先创建模型HelloModel,它是一个简单的Java bean。
- 创建一个控制器HelloEditPart。一般来说,控制器都是继承自org.eclipse.gef.editparts.AbstractGraphicalEditPart。它有两个抽象方法需要实现:createFigure()方法定义用来在视图中显示的图形,本例是显示一个Label;createEditPolicies()用来安装Edit Policy(暂不涉及)。
protected IFigure createFigure() {
HelloModel model = (HelloModel) getModel();
Label label = new Label(); //是org.eclipse.draw2d.Label
label.setText(model.getText());
return label;
} - 使用工厂连接模型与控制器。创建实现了EditPartFactory接口的PartFactory类。
public EditPart createEditPart(EditPart context, Object model) {
EditPart part = getPartForElement(model);
// 通过setModel()方法连接模型与控制器。这样从EditPart就可以通过getModel()方法取得对应的模型。
part.setModel(model);
return part;
}
/**
- Maps an object to an EditPart.
*/
private EditPart getPartForElement(Object modelElement) {
// 根据模型类型创建控制器,每种模型对应一种控制器。
if (modelElement instanceof HelloModel)
return new HelloEditPart();
throw new RuntimeException(“Can’t create part for model element: ”
- ((modelElement != null) ? modelElement.getClass().getName() : “null”));
}
- ((modelElement != null) ? modelElement.getClass().getName() : “null”));
- Maps an object to an EditPart.
- 创建视图。
GEF有两类视图,图形化视图(GraphicalViewer)和树状视图(TreeViewer),它们都源自EditPartViewer接口。
EditPartViewer管理EditParts的整个生命周期,并且通过EditParts的visuals,如TreeItems或Figures,将模型显示出来。
EditPartViewer本身是一个ISelectionProvider,它维护了一个选中EditParts的列表,该列表永不为空,无选中EditPart时就用viewer的contents。
contents可视为viewer的input,一般是由项目定义的模型实例组成。contents经由EditPartFactory创建出对应的EditParts,并被置入root editpart。当然,也可以为contents自定义一个相应的EditPart。
本例使用内含在GraphicalEditor中的GraphicalViewer。
查看GraphicalEditor的createPartControl()方法,它创建了一个GraphicalViewer接口的实现类ScrollingGraphicalViewer作为自己的GraphicalViewer,然后顺序调用了以下3个方法:
configureGraphicalViewer(); 在GraphicalViewer接受contents前设置GraphicalViewer,一般用来设置root editpart和editpart factory。
hookGraphicalViewer(); 将该GraphicalViewer加入到SelectionSynchronizer,用来同步多个EditPartViewer;同时将该GraphicalViewer注册为selection provider。
initializeGraphicalViewer(); 在这里通过setContents()方法为GraphicalViewer设置输入内容(GraphicalViewer可以类比为jface的TreeViewer,setContents()方法就类似于setInput()方法)。此外,与selection有关的代码也应该放在这儿。
GEF 和 eclipse 视图对象
最新推荐文章于 2024-08-06 09:02:23 发布