GEF框架学习(1)
作者:互联网
写在前面
最近终于是成功入职了,但万万没想到干的是JAVA客户端。导师给我安排的试用期任务是做图形化,类似于C#中的组件拖拽。但不同的是使用的是Eclipse旗下的一个框架:GEF。
本系列博客主要参考:GEF入门Demo (github.com)
GEF框架简介
GEF,全称Graphical Editing Framework
,是一个图形化编辑框架,可以用来制作诸如UML类图编辑器,XML编辑器等等。从描述来看,十分适合做拖拽控件之类的操作。但救我个人体验来看,完全体现出了JAVA的代码冗长。
HelloWorld
建立工程
首先自然是经典的HelloWorld了。这里选择建立一个RCP工程。
这里选择RCP 3.x,创建一个最简单的项目。并在plugin.xml中加上gef的依赖:
这样我们就有了一个最基本的项目了。接下来我们来创建最重要的Editor。我们既然要拖拽控件,那么肯定有放控件的地方。这个地方就是Editor。通过plugin.xml里的图形化界面来创建一个新的Editor,并更改ID等:
接下来创建一个GEF项目最基本的三个包:model,editparts,ui。其中model包主要放置和模型相关的类,ui包不用多说,自然是放置Editor和EditorInput类。而editparts包则比较特殊,在GEF框架中,我们需要editparts来充当controller的角色来监听和管理事件。
首先我们在ui包下创建一个DigramEditor
类,并让他继承GraphicalEditor
类。这个类是GEF包提供的一个类,可以帮助我们创建显示GEF图形的viewer。并且给他设置一个ID用来标识Editor,如下:
然后我们回到plugin.xml里的extension界面,把我们刚创建的类与创建的拓展点链接起来:
显示Editor
接下来就要想办法显示这个我们刚创建的Editor了。我们可以通过菜单来开启一个空白的Editor。要添加一个菜单需要如下步骤:
-
首先要有一个Action的派生类,这里命名为DiagramAction,放到actions包下。
public class DiagramAction extends Action implements ISelectionListener,IWorkbenchAction{ private final IWorkbenchWindow window; public final static String ID = "hellogef.diagram"; private IStructuredSelection selection; public DiagramAction(IWorkbenchWindow window) { this.window = window; setId(ID); setText("&Diagram"); setToolTipText("Draw the GEF diagram"); setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, "icons/eclipse16.png")); window.getSelectionService().addSelectionListener(this); } @Override public void run() { } @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { } @Override public void dispose() { window.getSelectionService().removeSelectionListener(this); } }
这里用到了Application中的ID,在Application文件中加入如下:
public static final String PLUGIN_ID = "hellogef";
-
创建一个ApplicationActionBarAdvisor,继承ActionBarAdvisor类,在里面加几个菜单:
public class ApplicationActionBarAdvisor extends ActionBarAdvisor{ private IWorkbenchAction exitAction; private IWorkbenchAction aboutAction; private DiagramAction diagramAction; public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { super(configurer); } @Override protected void makeActions(IWorkbenchWindow window) { exitAction = ActionFactory.QUIT.create(window); register(exitAction); aboutAction = ActionFactory.ABOUT.create(window); register(aboutAction); diagramAction = new DiagramAction(window); register(diagramAction); } @Override protected void fillMenuBar(IMenuManager menuBar) { MenuManager fileMenu = new MenuManager("&File","File"); fileMenu.add(diagramAction); fileMenu.add(new Separator()); fileMenu.add(exitAction); MenuManager helpMenu = new MenuManager("&Help","help"); helpMenu.add(aboutAction); menuBar.add(fileMenu); menuBar.add(helpMenu); } }
-
修改
ApplicationWorkbenchWindowAdvisor
中的createActionBarAdvisor
方法,让他返回咱们自己创建的ApplicationActionBarAdvisor
这样就可以显示我们的菜单了,但菜单点击是没有什么效果的:
接下来就要接着说如何显示DiagramEditor了。
-
因为所有的Editor都需要一个EditorInput来作为内容提供者,这里我们创建了一个
DiagramEditorInput
作为提供者:public class DiagramEditorInput implements IPathEditorInput { private IPath path; public DiagramEditorInput(IPath path) { this.path = path; } @Override public int hashCode() { return path.hashCode(); } @Override public boolean exists() { return path.toFile().exists(); } @Override public ImageDescriptor getImageDescriptor() { return null; } @Override public String getName() { return path.toString(); } @Override public IPersistableElement getPersistable() { return null; } @Override public String getToolTipText() { return null; } @Override public <T> T getAdapter(Class<T> adapter) { return null; } @Override public IPath getPath() { return path; } }
-
在DiagramAction中的run函数添加代码让Diagram菜单打开一个文件选择器,拓展名为*.diagram:
@Override public void run() { String path = openFileDialog(); if(path != null) { IEditorInput input = new DiagramEditorInput(new Path(path)); IWorkbenchPage page = window.getActivePage(); try { page.openEditor(input, DiagramEditor.ID,true); } catch (PartInitException e) { e.printStackTrace(); } } } private String openFileDialog() { FileDialog dialog = new FileDialog(window.getShell(),SWT.OPEN); dialog.setText("GEF文件"); dialog.setFilterExtensions(new String[] {".diagram"}); return dialog.open(); }
-
在Perspective里设置Editor可见:
layout.setEditorAreaVisible(true);
-
最后在DiagramEditor的构造函数中加入一行代码:
setEditDomain(new DefaultEditDomain(this));
这样子我们就可以显示一个空白的Editor了:
在Editor上画几个框框
为了要在Editor上画几个框框,我们要按照GEF的套路来。这也是我觉得这个框架最为麻烦的地方。如图所示:
创建模型
因为我们只是想显示一个HelloWorld而已,因此这里就写一个HelloModel,把他放到model包下:
public class HelloModel{
private String text = "HelloWorld";
public String getText(){
return text;
}
public void setText(String text) {
this.text = text;
}
}
创建控制器
所谓的控制器即Controller,不过在GEF中它叫EditPart。这里创建一个HelloEditPart,让他继承AbstractGraphicalEditPart:
public class HelloEditPart extends AbstractGraphicalEditPart{
@Override
protected IFigure createFigure(){
HelloModel model = (HelloModel)getModel();
Label label = new Label();
label.setText(model.getText());
return label;
}
@Override
protected void createEditPolicies(){
}
}
连接控制器和模型
GEF使用工厂模式来连接控制器和模型。如何连接呢?简单地说是两步,一,根据类型创建控制器,二,通过SetModel连接模型和控制器。
public class PartFactory implements EditPartFactory{
@Override
public EditPart createEditPart(EditPart arg0, Object model) {
// 1.根据模型类型创建其控制器
EditPart part = getPartForElement(model);
// 2.连接模型和控制器
part.setModel(model);
return part;
}
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"));
}
}
创建View
下面就是要在DiagramEditor中创建Viewer了,用来显示HelloEditPart显示的图形。这里使用的是GraphicalViewer。在initializeGraphicalViewer
函数接收HelloModel之前,我们要先初始化GraphicalViewer,如下:
@Override
protected void configureGraphicalViewer() {
super.configureGraphicalViewer();
viewer = getGraphicalViewer();
viewer.setEditPartFactory(new PartFactory());
}
@Override
protected void initializeGraphicalViewer() {
viewer.setContents(new HelloModel());
}
见证结果
终于,经历了这么多步骤后,我们终于HelloWorld了:
总结
从一个简单的HelloWorld就可看出JAVA语言在客户端开发上的劣势了。怪不得被淘汰了。这个系列会慢慢写下去,但不知道更新频率能否保证了,毕竟现在工作了。还是尽量逼自己输出一些内容吧。
标签:return,框架,学习,GEF,Override,new,public,Editor 来源: https://www.cnblogs.com/wushenjiang/p/16526781.html