ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GEF框架学习(1)

2022-07-27 22:31:10  阅读:146  来源: 互联网

标签:return 框架 学习 GEF Override new public Editor


写在前面

最近终于是成功入职了,但万万没想到干的是JAVA客户端。导师给我安排的试用期任务是做图形化,类似于C#中的组件拖拽。但不同的是使用的是Eclipse旗下的一个框架:GEF。

本系列博客主要参考:GEF入门Demo (github.com)

GEF框架简介

GEF,全称Graphical Editing Framework,是一个图形化编辑框架,可以用来制作诸如UML类图编辑器,XML编辑器等等。从描述来看,十分适合做拖拽控件之类的操作。但救我个人体验来看,完全体现出了JAVA的代码冗长。

HelloWorld

建立工程

首先自然是经典的HelloWorld了。这里选择建立一个RCP工程。

image-20220727214528747

这里选择RCP 3.x,创建一个最简单的项目。并在plugin.xml中加上gef的依赖:

image-20220727214624897

这样我们就有了一个最基本的项目了。接下来我们来创建最重要的Editor。我们既然要拖拽控件,那么肯定有放控件的地方。这个地方就是Editor。通过plugin.xml里的图形化界面来创建一个新的Editor,并更改ID等:

image-20220727214821845

接下来创建一个GEF项目最基本的三个包:model,editparts,ui。其中model包主要放置和模型相关的类,ui包不用多说,自然是放置Editor和EditorInput类。而editparts包则比较特殊,在GEF框架中,我们需要editparts来充当controller的角色来监听和管理事件。

首先我们在ui包下创建一个DigramEditor类,并让他继承GraphicalEditor类。这个类是GEF包提供的一个类,可以帮助我们创建显示GEF图形的viewer。并且给他设置一个ID用来标识Editor,如下:

image-20220727215524733

然后我们回到plugin.xml里的extension界面,把我们刚创建的类与创建的拓展点链接起来:

image-20220727215634136

显示Editor

接下来就要想办法显示这个我们刚创建的Editor了。我们可以通过菜单来开启一个空白的Editor。要添加一个菜单需要如下步骤:

  1. 首先要有一个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";
    
  2. 创建一个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);
    		
    	}
    
    }
    
  3. 修改ApplicationWorkbenchWindowAdvisor中的createActionBarAdvisor方法,让他返回咱们自己创建的ApplicationActionBarAdvisor

这样就可以显示我们的菜单了,但菜单点击是没有什么效果的:

image-20220727220245471

接下来就要接着说如何显示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了:

image-20220727220642935

在Editor上画几个框框

为了要在Editor上画几个框框,我们要按照GEF的套路来。这也是我觉得这个框架最为麻烦的地方。如图所示:

image-20220727220903345

创建模型

因为我们只是想显示一个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了:

image-20220727221908897

总结

从一个简单的HelloWorld就可看出JAVA语言在客户端开发上的劣势了。怪不得被淘汰了。这个系列会慢慢写下去,但不知道更新频率能否保证了,毕竟现在工作了。还是尽量逼自己输出一些内容吧。

标签:return,框架,学习,GEF,Override,new,public,Editor
来源: https://www.cnblogs.com/wushenjiang/p/16526781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有