Rcp Edit 扩展编辑器

23.3 扩展编辑器
    编辑器与视图一样,是工作台页面内的可视组件。通常用来编辑文件(例如查源代码)或查看输入对象(例如打开的plugin.xml文件时的页面)。用于创建视图的扩展点为org.eclipse.ui.editors。

1. 编辑器扩展点
    在扩展编辑器中新增扩展点,配置好的plugin.xml文件如下:
   <extension
         point="org.eclipse.ui.editors">
      <editor
            class="com.testrcp.myrcp.editors.JsEditor"
            contributorClass="com.testrcp.myrcp.editors.JsEditorContributor"
            default="false"
            icon="icons/alt_about.gif"
            id="com.testrcp.myrcp.editors.JsEditor"
            name="JsEditor">
      </editor>
   </extension>
    编辑器扩展点的各元素的说明如下:
    ◇ 编辑器的扩展点类型是org.eclipse.ui.editors。
    ◇ 与视图一样,一个编辑器对应一个class类,该类必须是实现了org.eclipse.ui.IEditorPart的类。
    ◇ id是该编辑器对象的唯一标识,name为编辑器显示的名称。
    ◇ default:表示是否使用默认的编辑器。
    ◇ contributorClass是实现了org.eclipse.ui.IEditorActionBarContributor接口的类,Eclipse中EditorActionBarContributor类已经实现了该接口,通常的做法是继承该类,然后覆盖父类中的方法实现的。
    ◇ 其他需要注意的元素如下:
        ⊙ extensions:打开该编辑器的所对应的文件的扩展名,例如“htm,html”。
        ⊙ command和launcher:command为要运行以启动外部编辑器的命令。launcher为实现了org.eclipse.ui.IEditorLauncher的类。这样启动程序将打开外部编辑器。其中class、command和launcher都是打开编辑器的方式,属性是互斥的。
        ⊙ filenames:编辑器打开文件时可选的文件名。
        ⊙ symbolicFontName:编辑器字体的名称。
        ⊙ matchingStrategy:实现org.eclipse.ui.IEditorMatchingStrategy的类。这运行编辑器扩展提供一个策略,是编辑器的输入与指定的编辑器输入相匹配。

    一般开发编辑器时通常会用到这些属性,但在RCP开发中,如果不是开发的RCP编辑器程序,一般是用不到这些属性的。

2. 编辑器类
    本例中的编辑器类是JsEditor,代码如下:
package com.testrcp.myrcp.editors;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

public class JsEditor extends EditorPart {
//对应plugin.xml指定的id
public static final String ID = "com.testrcp.myrcp.editors.JsEditor";
private Text text;
//编辑器中的内容是否被修改的标志
private boolean bDirty = false;
public JsEditor() {
   super();
}
//初始化编辑器
public void init(IEditorSite site, IEditorInput input)
    throws PartInitException {
   this.setSite(site);//设置site
   this.setInput(input);//设置输入的IEditorInput对象
   this.setPartName(input.getName());//设置编辑器上方显示的名称
}
//创建编辑器中的控件
public void createPartControl(Composite parent) {
   text = new Text(parent, SWT.NONE);
   //当文本框修改时,设定内容被修改过
   text.addModifyListener(new ModifyListener() {
    public void modifyText(ModifyEvent e) {
     if (!isDirty()) {//如果未修改
      setDirty(true);//设置修改
      //更改编辑器的状态
      firePropertyChange(IEditorPart.PROP_DIRTY);
     }
    }
   });
}
//编辑器关闭时,保存编辑器内容时所调用的方法
public void doSave(IProgressMonitor monitor) {
   //将保存状态显示在状态栏中
   try {
    monitor.beginTask("保存文件...", 100);

    for (int i = 0; i < 10 && !monitor.isCanceled(); i++) {
     Thread.sleep(500);
     monitor.worked(10);
     double d = (i + 1) / 10d;
     monitor.subTask("已完成" + d * 100 + "%");// 显示任务状态
    }
    monitor.done();
    if (monitor.isCanceled())
     throw new InterruptedException("取消保存");
   } catch (InterruptedException e) {
    ;
   }
}
//另存为调用的方法
public void doSaveAs() {

}
//判断是否被修改过
public boolean isDirty() {
   return bDirty;
}
//是否允许保存
public boolean isSaveAsAllowed() {
   return true;
}
//设置焦点
public void setFocus() {
   text.setFocus();
}
//设置编辑器内容被修改过
public void setDirty(boolean b) {
   bDirty = b;
}

}

    创建编辑器时应注意以下问题:
    ◇ 编辑器所对应的类为实现了IEditorPart接口的类。本例中使用的是继承了EditorPart类,例如下文中讲述的多页编辑器则要继承自MultiPageEditorPart类,表单编辑器则要继承FormEditor类。
    ◇ 编辑器中显示的控件通过createPartControl方法创建。
    ◇ isDirty():编辑器内容是否被修改过,如果被修改过,标签上会显示一个“*”号。当状态改变时要及时的更新界面效果,使用下面的方法:
      firePropertyChange(IEditorPart.PROP_DIRTY);
        ⊙ isSaveAsAllowed():是否允许全部保存。
        ⊙ doSaveAs():另存时调用的方法。
        ⊙ doSave():保存时调用的方法。
        ⊙ setFocus():设置编辑器激活时焦点所在的控件。

3. 打开编辑器
    与视图不同,编辑器不能直接显示到透视图的某一个区域,而是由一项操作所打开的,通常使用IWorkbenchPage的以下两个方法:
    ◇ openEditor(IEditorInput input, String editorId):input对象为打开文件器时所指定输入到编辑器的内容,为了实现IEditorInput接口,editorId为编辑器的唯一标识。
    ◇ openEditor(IEditorId input, String editorId, boolean activate):activate表示是否打开后并激活该编辑器。
    本例中所创建的实现了接口的类为JsEditorInput类,代码如下:
package com.testrcp.myrcp.editors;

import myrcp.Activator;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;

public class JsEditorInput implements IEditorInput {
//输入的字符
private String input ;
public JsEditorInput ( String input ){
   this.input = input ;
}
//是否将编辑器保存在最近访问记录中
public boolean exists() {
   return true;
}
//输入内容的图标
public ImageDescriptor getImageDescriptor() {
   return Activator.getImageDescriptor("icons/samples.gif");
}
//输入信息的名称
public String getName() {
   return input;
}
//是否可以持久化该编辑器
public IPersistableElement getPersistable() {
   return null;
}
//设置编辑器标签中显示提示信息
public String getToolTipText() {
   return input;
}
//返回与该输入相关的类的对象
public Object getAdapter(Class adapter) {
   return null;
}

}

    这些方法都是IEditorInput接口中的方法。另外除了可以自己实现该接口的类外,Eclipse中已经有一些实现了该接口的类,可以直接使用或者通过继承的方法。实现IEditorInput接口的类如下:
    CommonSourceNotFoundEditorInput, CompareEditorInput, FileEditorInput, FileInPlaceEditorInput, FileStoreEditorInput, HistoryPageCompareEditorInput, MultiEditorInput, PageCompareEditorInput, ParticipantPageCompareEditorInput, SaveableCompareEditorInput, SyncInfoCompareInput

    创建了打开编辑器输入内容的类,也有了对应的编辑器,就可以打开编辑器了。要想打开编辑器,还需要创建一个视图,视图中放置了一个列表List,然后单击列表中的一项来打开编辑器。plugin.xml中的配置代码如下:
      <view
            class="com.testrcp.myrcp.views.OpenEditorView"
            icon="icons/alt_launcher.ico"
            id="com.testrcp.myrcp.views.OpenEditorView"
            name="打开编辑器">
      </view>

    后面的代码需要在项目中增加一个jar包:org.eclipse.ui.forms_3.5.0.v20100427.jar,在Eclipse的安装目录下的plugins目录中可以找到。

    对应的视图类如下:
package com.testrcp.myrcp.views;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.internal.part.NullEditorInput;
import org.eclipse.ui.part.ViewPart;

import com.testrcp.myrcp.editors.JsEditor;
import com.testrcp.myrcp.editors.JsEditorInput;
import com.testrcp.myrcp.editors.MutiEditorSample;
import com.testrcp.myrcp.forms.MyMutiForm;

public class OpenEditorView extends ViewPart {
public static final String ID = "com.testrcp.myrcp.views.OpenEditorView";

public List list;

public OpenEditorView() {
   super();
}

public void createPartControl(Composite parent) {
   list = new List(parent, SWT.NONE);
   list.add("Editor");
   list.add("MutiPage Editor");
   list.add("Form Editor");
   list.add("Master/Detail Page");
   list.addSelectionListener(new SelectionAdapter() {
    public void widgetSelected(SelectionEvent e) {

     String select = list.getSelection()[0];
     // 获得当前激活的IWorkbenchPage对象
     IWorkbenchPage page = getViewSite().getWorkbenchWindow().getActivePage();
     try {
      if (select.equals("Editor")) {// 如果选中的"Editor"一项
       // 创建输入的内容对象
       JsEditorInput editor = new JsEditorInput(select);
       // 打开该编辑器
       page.openEditor(editor, JsEditor.ID);

      } else if (select.equals("MutiPage Editor")) {// 如果选中的"Editor"一项
       page.openEditor(new NullEditorInput(), MutiEditorSample.ID);

      }else if (select.equals("Form Editor")) {// 如果选中的"Editor"一项
        page.openEditor(new NullEditorInput(), MyMutiForm.ID);
      }
     } catch (PartInitException ee) {
      ee.printStackTrace();
     }
    
    }

   });
}

public void setFocus() {
   list.setFocus();
}
}


4. 添加编辑器的菜单和工具栏
    对于编辑器,也可以设置编辑器所对应的菜单、工具栏和上下文菜单。实现这些功能需要实现IEditorActionBarContributor接口,EditorActionBarContributor类实现了该接口。代码如下:
package com.testrcp.myrcp.editors;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorActionBarContributor;

public class JsEditorContributor extends EditorActionBarContributor {

private Action action1 ;
private Action action2 ;
public JsEditorContributor() {
   super();
   makeActions();
}
public void makeActions() {
   action1 = new Action() {
    public void run() {
    
    }
   };
   action1.setText("Action 1");
   action1.setToolTipText("Action 1 tooltip");
   action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
    getImageDescriptor(ISharedImages.IMG_DEF_VIEW));
  
   action2 = new Action() {
    public void run() {
    
    }
   };
   action2.setText("Action 2");
   action2.setToolTipText("Action 2 tooltip");
   action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
     getImageDescriptor(ISharedImages.IMG_OBJS_WARN_TSK));
}
//覆盖父类中的方法,创建菜单
public void contributeToMenu(IMenuManager menuManager) {
   MenuManager editMenu = new MenuManager("编辑器菜单");
   editMenu.add( action1 );
   editMenu.add( action2 );
   menuManager.add( editMenu );
}
//覆盖父类的方法,创建工具栏
public void contributeToToolBar(IToolBarManager toolBarManager) {
   toolBarManager.add( action1 );
   toolBarManager.add( action2 );
}
}
    其中,创建菜单栏和工具栏的方法分别是覆盖父类中的contributeToMenu和contributeToToolBar方法。

    在Perspective类的createInitialLayout方法中只留下下面两行代码:
   String editorArea = layout.getEditorArea();
   layout.addStandaloneView(OpenEditorView.ID,true,IPageLayout.RIGHT,.3f,editorArea);

    运行后的显示效果如下:

    点击“Editor”行,显示效果如下:

多点击几次Editor,出现多个Editor,如下图:


菜单如下图:


点击除“Editor”外的项时,菜单效果如下图:



5. 多页编辑器
    多页编辑器可以同时打开多个页面,每个页面可以是一个编辑器IEditorPart,也可以是普通控件Control。

    在plugin.xml配置一个新的编辑器。内容如下:
   <extension
         point="org.eclipse.ui.editors">
      <editor
            class="com.testrcp.myrcp.editors.MutiEditorSample"
            default="false"
            icon="icons/alt_window_16.gif"
            id="com.testrcp.myrcp.editors.MutiEditorSample"
            name="多页编辑器">
      </editor>
   </extension>

    该编辑器对应的类为MutiEditorSample,该类要继承自MultiPageEditorPart类才可以实现多页显示效果。代码如下:
package com.testrcp.myrcp.editors;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.MultiPageEditorPart;

public class MutiEditorSample extends MultiPageEditorPart {

//该编辑器的标识
public static final String ID = "com.testrcp.myrcp.editors.MutiEditorSample";
private JsEditor page1 ;//编辑器对象
private JsEditor page2 ;//编辑器对象
private Label control1 ;//标签对象
//父类中抽象方法
protected void createPages() {
   //创建页面和标签对象
   page1 = new JsEditor();
   page2 = new JsEditor();
   control1 = new Label ( getContainer(), SWT.NONE);
   control1.setText("这是一个标签");
   try {
    //添加第一页
   addPage( page1 , new JsEditorInput("One"));
    //设置选项卡的名称
    setPageText(0,"One");
    //添加第二页
    addPage( page2 , new JsEditorInput("Two"));
    setPageText(1,"Two");
    //添加第三页,为一个标签
    addPage(control1);
    setPageText(2,"Three");
   } catch (PartInitException e) {
    e.printStackTrace();
   }
}

public void doSave(IProgressMonitor monitor) {
  
}

public void doSaveAs() {
  
}

public boolean isSaveAsAllowed() {
   return false;
}


}

    创建多页编辑器时应注意以下几个问题:
    ◇ 该类必须继承自MultiPageEditorPart类。
    ◇ 创建页面的代码是在createPages方法中。
    ◇ 每个页面可以是IEditorPart对象,也可以是Control对象。
    ◇ 创建完页面后要调用addPage方法,将该页添加。如果不使用该方法,将不会显示页面。
    ◇ addPage方法如下所示:
        ◇ addPage(Control control):添加一个控件,其中control为选项卡中的控件对象。
        ◇ addPage(IEditorPart editor, IEditorInput input):添加一个编辑页面。
        ◇ addPage(int index, Control control):在指定索引的选项卡中,添加一个控件。
        ◇ addPage(int index, IEditorPart editor, IEditorInput input):在指定索引的选项卡中,添加一个编辑页面。
    ◇ 可以使用父类的setPageText(int pageIndex, String text)方法设定显示选项卡的名称。

    注意:MutiEditorSample 对应的扩展点是 org.eclipse.ui.editors,而不是 org.eclipse.ui.views,不小心搞错了,在点击“MutiPage Editor”时,总是出现下面的异常:
org.eclipse.ui.PartInitException: Unable to open editor, unknown editor ID: com.testrcp.myrcp.editors.MutiEditorSample

多页编辑器的显示效果如下:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值