Eclipse SWT/JFACE 核心应用

EclipseSWT/JFACE核心应用》清华大学出版社 23 RCP开发

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() {
   returnActivator.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 = newJsEditorInput(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(newNullEditorInput(), 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 extendsEditorActionBarContributor {

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, IEditorInputinput) :添加一个编辑页面。
       
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

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

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值