专栏首页Java成神之路Eclipse插件开发_学习_02_GEF入门实例

Eclipse插件开发_学习_02_GEF入门实例

一、前言

这一节,我们将会创建一个GEF入门实例

二、新建RCP项目

1. New 一个 Plug-in Project

2.输入项目名

项目名:com.ray.gef.helloworld

 3.Content页

勾选下面三处

说明:

1处:生成一个Activator,用于管理插件的生命周期

3处:是否想要创建一个RCP程序,选择是

4.模板

选择最小的模板

5.添加依赖

到这一步,项目已经创建好了,不过我们还需要引入GEF相关依赖

打开 plugin.xml ,选择 Dependencies,添加如下GEF依赖

6.修改工程目录结构

将目录修改成如下结构:

三、创建Editor

1.添加editor扩展

(1)双击plugin.xml,在extensions页中,点击Add...,

(2)搜索 editors,选择 org.eclipse.ui.editors  扩展点,finish

 (3) 在新添加的 org.eclipse.ui.editors  扩展点上右键 -> New -> editor,出现下图

 (4)填写扩展节点的详情

id        :  com.ray.gef.helloworld.view.editor.DiagramEditor

name  :  Diagram Editor

icon    :   icons/gar.ico

class  :   com.ray.gef.helloworld.view.editor.DiagramEditor

default : false

 (5) 如下图,点击class ,会出现一个创建class的对话框。修改集成的基类为:org.eclipse.gef.ui.parts.GraphicalEditor,

然后点击finish。

即可创建Editor

 2.修改 DiagramEditor  类

 添加 Editor_ID,记得与plugin.xml中设置的Editor ID一致。为了避免出现问题,我们所有地方的ID,均设置成全类名的形式。

package com.ray.gef.helloworld.view.editor;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.ui.parts.GraphicalEditor;

public class DiagramEditor extends GraphicalEditor {
    public static final String EDITOR_ID = "com.ray.gef.helloworld.view.editor.DiagramEditor";
    
    public DiagramEditor() {
          setEditDomain(new DefaultEditDomain(this));
    }

    @Override
    protected void initializeGraphicalViewer() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doSave(IProgressMonitor monitor) {
        // TODO Auto-generated method stub

    }

}

四、创建Action

现在编辑器editor已经创建好了,我们得想办法让editor显示出来。

下面我们将创建一个菜单,点击菜单按钮将会创建一个空白的Editor页面。

1.创建常量类 IImageConstant

package com.ray.gef.helloworld.constant;

public interface IImageConstant {

    public static final String EDITORTITLE = "icons/example.gif";

    public static final String NEWHELLOMODEL = "icons/newModel.gif";

    public static final String NEWCONNECTION = "icons/newConnection.gif";

    public static final String ARROWCONNECTION = "icons/arrowConnection.gif";

}

2.创建编辑器输入 DiagramEditorInput 

package com.ray.gef.helloworld.view.editor.input;



import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IPersistableElement;

public class DiagramEditorInput implements IPathEditorInput {

    private IPath path;

    public DiagramEditorInput(IPath path) {
        this.path = path;
    }

    public IPath getPath() {
        return path;
    }

    public boolean exists() {
        return path.toFile().exists();
    }

    public ImageDescriptor getImageDescriptor() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getName() {
        return path.toString();
    }

    public IPersistableElement getPersistable() {
        return null;
    }

    public String getToolTipText() {
        return path.toString();
    }

    public Object getAdapter(Class adapter) {
        // TODO Auto-generated method stub
        return null;
    }

    //add by Bin Wu
    public int hashCode() {
        return path.hashCode();
    }
    
    
    
}

3.创建action  DiagramAction

package com.ray.gef.helloworld.action;


import org.eclipse.core.runtime.Path;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import com.ray.gef.helloworld.app.Application;
import com.ray.gef.helloworld.constant.IImageConstant;
import com.ray.gef.helloworld.view.editor.DiagramEditor;
import com.ray.gef.helloworld.view.editor.input.DiagramEditorInput;

public class DiagramAction extends Action implements ISelectionListener,
        IWorkbenchAction {

    private final IWorkbenchWindow window;
    public final static String ID = "com.ray.gef.helloworld.action.DiagramAction";
    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, IImageConstant.EDITORTITLE));
        window.getSelectionService().addSelectionListener(this);
    }

    public void dispose() {
        window.getSelectionService().removeSelectionListener(this);
    }

    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        // TODO Auto-generated method stub
        
    }

    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.EDITOR_ID,true);
            } catch (PartInitException e) {
                // handle error
            }
        }
    }

    private String openFileDialog() {
        FileDialog dialog = new FileDialog(window.getShell(), SWT.OPEN);
        dialog.setText("??");
        dialog.setFilterExtensions(new String[] { ".diagram" });
        return dialog.open();
    }
}

4.Application.java

在Application.java中加入插件ID

package com.ray.gef.helloworld.app;

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;

/**
 * This class controls all aspects of the application's execution
 */
public class Application implements IApplication {

    public static final String PLUGIN_ID = "com.ray.gef.helloworld";
    
    @Override
    public Object start(IApplicationContext context) throws Exception {
        Display display = PlatformUI.createDisplay();
        try {
            int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
            if (returnCode == PlatformUI.RETURN_RESTART)
                return IApplication.EXIT_RESTART;
            else
                return IApplication.EXIT_OK;
        } finally {
            display.dispose();
        }
        
    }

    @Override
    public void stop() {
        if (!PlatformUI.isWorkbenchRunning())
            return;
        final IWorkbench workbench = PlatformUI.getWorkbench();
        final Display display = workbench.getDisplay();
        display.syncExec(new Runnable() {
            public void run() {
                if (!display.isDisposed())
                    workbench.close();
            }
        });
    }
}

5.ApplicationActionBarAdvisor

在 ApplicationActionBarAdvisor.java  中添加Action,并生成菜单

package com.ray.gef.helloworld.app;

import org.eclipse.jface.action.ICoolBarManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

import com.ray.gef.helloworld.action.DiagramAction;


/**
 * An action bar advisor is responsible for creating, adding, and disposing of
 * the actions added to a workbench window. Each window will be populated with
 * new actions.
 */
public class ApplicationActionBarAdvisor extends ActionBarAdvisor {

    // Actions - important to allocate these only in makeActions, and then use
    // them
    // in the fill methods. This ensures that the actions aren't recreated
    // when fillActionBars is called with FILL_PROXY.

    private IWorkbenchAction exitAction;
    private IWorkbenchAction aboutAction;
    private DiagramAction diagramAction;

    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
        super(configurer);
    }

    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);
    }

    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);
    }

    protected void fillCoolBar(ICoolBarManager coolBar) {
        IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
        coolBar.add(toolbar);
    }

}

6. ApplicationWorkbenchWindowAdvisor

在ApplicationWorkbenchWindowAdvisor 中修改创建的 ActionBarAdvisor 为其自子类 ApplicationActionBarAdvisor

package com.ray.gef.helloworld.app;

import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;

public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        super(configurer);
    }
    
    @Override
    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { 
        return new ApplicationActionBarAdvisor(configurer);
    }
    
    @Override
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        configurer.setInitialSize(new Point(400, 300));
        configurer.setShowCoolBar(false);
        configurer.setShowStatusLine(false);
        configurer.setTitle("Hello RCP"); //$NON-NLS-1$
    }
}

7.Perspective

加入 代表此透视图的常量 PERSPECTIVE_ID,并设置显示编辑器区域

package gef.tutorial.step;

import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {
    public static final String PERSPECTIVE_ID = "gef.tutorial.step.perspective";
    
    @Override
    public void createInitialLayout(IPageLayout layout) {
        layout.setEditorAreaVisible(true);
        layout.setFixed(true);
        
    }

}

8.ApplicationWorkbenchAdvisor

设置要一开始要打开的透视图

package gef.tutorial.step;

import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;

public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {

    

    @Override
    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
            IWorkbenchWindowConfigurer configurer) {
        return new ApplicationWorkbenchWindowAdvisor(configurer);
    }
    
    @Override
    public String getInitialWindowPerspectiveId() {
        return Perspective.PERSPECTIVE_ID;
    }

}

9.运行插件

这时我们点击plugin.xml 的OverView页中的 launch an Eclipse application 来运行插件,发现有两个菜单。

点击File子菜单Diagram,将弹出一个文件对话框,就是让你选择新建的文件。

然后Finish,将打开DiagramEditor 。

五、为Editor添加内容

下面我们将为这个Editor (View)添加内容。首先创建一个模型

1.创建model

HelloModel

package com.ray.gef.helloworld.model;

public class HelloModel {
    private String text = "Hello World";

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }


}

2.创建控制器

创建一个连接视图和模型的控制器

(1)EditorPart

HelloEditorPart

package com.ray.gef.helloworld.part;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;

import com.ray.gef.helloworld.model.HelloModel;



public class HelloEditorPart extends AbstractGraphicalEditPart {

    @Override
    protected IFigure createFigure() {
        HelloModel model = (HelloModel)getModel();

        Label label = new Label();
        label.setText(model.getText());

        label.setBorder(new CompoundBorder(new LineBorder(), new MarginBorder(3)));

        //设置背景颜色
        label.setBackgroundColor(ColorConstants.orange);

        label.setOpaque(true);

        return label;
    }

    @Override
    protected void createEditPolicies() {
        // TODO Auto-generated method stub

    }

}

(2) EditorPartFactory

连接模型与控制器

PartFactory

package com.ray.gef.helloworld.part;


import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;

import com.ray.gef.helloworld.model.HelloModel;


public class PartFactory implements EditPartFactory {

    //------------------------------------------------------------------------
    // Abstract methods from EditPartFactory

    public EditPart createEditPart(EditPart context, Object model) {

        //get EditPart for model element
        EditPart part = getPartForElement(model);
        //store model element in EditPart
        part.setModel(model); 
        return part;
    }

    /**
     * Maps an object to an EditPart. 
     * @throws RuntimeException if no match was found (programming error)
     */
    private EditPart getPartForElement(Object modelElement) {
        //根据模型类创建其控制器
        if (modelElement instanceof HelloModel)
            return new HelloEditorPart();


        throw new RuntimeException(
                "Can't create part for model element: "
                        + ((modelElement != null) ? modelElement.getClass().getName() : "null"));
    }

}

3.创建视图View

在 DiagramEditor 中创建view,我们这里创建一个 GraphicalViewer,

DiagramEditor

package com.ray.gef.helloworld.view.editor;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.ui.parts.GraphicalEditor;

import com.ray.gef.helloworld.model.HelloModel;
import com.ray.gef.helloworld.part.PartFactory;

public class DiagramEditor extends GraphicalEditor {
    public static final String EDITOR_ID = "com.ray.gef.helloworld.view.editor.DiagramEditor";
    GraphicalViewer viewer;
    
    public DiagramEditor() {
          setEditDomain(new DefaultEditDomain(this));
    }

    @Override
    protected void initializeGraphicalViewer() {
        // TODO Auto-generated method stub
        viewer.setContents(new HelloModel());
    }

    @Override
    protected void configureGraphicalViewer(){
        
        super.configureGraphicalViewer();
        viewer = getGraphicalViewer();
        viewer.setEditPartFactory(new PartFactory());
        
        
    }
    @Override
    public void doSave(IProgressMonitor monitor) {
        // TODO Auto-generated method stub

    }
}

4.运行项目

这时我们运行项目,点击File->diagrame,设置新文件名称,Finish,会出现下图。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • GEF入门实例_总结_05_显示一个空白编辑器

    在第三节( GEF入门实例_总结_03_显示菜单和工具栏  ),我们创建了菜单和工具栏。

    shirayner
  • GEF入门实例_总结_04_Eclipse插件启动流程分析

    这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们将通过这几个文件来了解Eclipse插件的启动过程。

    shirayner
  • GEF入门实例_总结_06_为编辑器添加内容

    GEF的MVC模式中的模型、控制器、视图分别对应于 Model 、EditPart、EditPartViewer。

    shirayner
  • GEF入门实例_总结_05_显示一个空白编辑器

    在第三节( GEF入门实例_总结_03_显示菜单和工具栏  ),我们创建了菜单和工具栏。

    shirayner
  • 一起来学 SpringBoot 2.x | 第十三篇:RabbitMQ 延迟队列

    延迟队列RabbitMQ 实现思路导入依赖属性配置具体编码定义队列实体类控制器消息消费者主函数测试总结说点什么

    芋道源码
  • Spring Boot:整合Shiro权限框架

    Shiro是Apache旗下的一个开源项目,它是一个非常易用的安全框架,提供了包括认证、授权、加密、会话管理等功能,与Spring Security一样属基于权...

    朝雨忆轻尘
  • springboot之单元测试

    https://wap.ztestin.com/site/register?usercode=FAAAQwMQGAAXAwQBA3QhExcDHAQDPjVaA...

    小老鼠
  • 一起来学SpringBoot | 第十三篇:RabbitMQ延迟队列

    初探RabbitMQ消息队列中介绍了 RabbitMQ的简单用法,顺带提及了下延迟队列的作用。所谓 延时消息就是指当消息被发送以后,并不想让消费者立即拿到消息,...

    battcn
  • java高级进阶|单机版限流之Ratelimiter

    好早之前写的一篇文章了,当时的感悟是,为什么要一直写文章呢?我也不知道,可能是为了将自己的内容做下总结吧,其实写的文章可能会用的很少,因为现在的项目基本上都有成...

    后端Coder
  • GEF入门实例_总结_04_Eclipse插件启动流程分析

    这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们将通过这几个文件来了解Eclipse插件的启动过程。

    shirayner

扫码关注云+社区

领取腾讯云代金券