给Eclipse插件的View加上菜单和工具条

简介: Eclipse的每个视图(View)都有自己的菜单和工具条,View通过与自己相关的IViewSite对象与这些东西打交道,确切的说,是通过这个IViewSite对象的IActionBars对象来管理,ActionBars对象负责菜单、工具条和状态栏。

Eclipse的每个视图(View)都有自己的菜单和工具条,View通过与自己相关的IViewSite对象与这些东西打交道,确切的说,是通过这个IViewSite对象的IActionBars对象来管理,ActionBars对象负责菜单、工具条和状态栏。

一个典型的View(继承org.eclipse.ui.part.ViewPart)的代码结构会是这样,作为例子,假设我们有三个功能项:Open、Remove和Reload,我们的View是一个简单的表格TableViewer,里面显示一些条目列表,允许用户进行多选:

TableViewer tvResult;
OpenAction openAction;
RemoveAction removeAction;
ReloadAction reloadAction;
public  void  createPartControl(Composite parent) { 
    
// 创建视图界面  
     
    
// 创建菜单  
    createActions(); 
    createMenu(); 
    createContextMenu(); 
    createToolbar(); 
    hookGlobalActions(); 

其中,createActions()是创建必要的IAction对象,这些对象可用在菜单、工具条里;createMenu()的作用是把刚刚创建的IAction对象放进与View相关的MenuManager里,就像前面所说,MenuManager可以通过getViewSite().getActionBars().getMenuManager()方法得到;createToolbar()则是把同样的对象放在工具条里,获得工具条的方法与菜单类似;createContextMenu()则是建立鼠标右键触发的上下文菜单,方法是建立一个新的MenuManager,然后由它建立一个Menu对象,再将Menu对象与控件联系;hookGlobalActions()的作用是把IAction对象与系统菜单(而不是View菜单联系),达到同一菜单项对不同View具有不同响应的效果。下面来看一下具体代码:

package net.sf.solo.actions; 
 
import java.io.IOException; 
import java.util.Iterator; 
import net.sf.solo.model.IInstance; 
import org.eclipse.jface.action.Action; 
import org.eclipse.jface.viewers.ISelectionChangedListener; 
import org.eclipse.jface.viewers.IStructuredSelection; 
import org.eclipse.jface.viewers.SelectionChangedEvent; 
 
public class OpenAction extends Action implements ISelectionChangedListener { 
 
    IStructuredSelection selection; 
 
    public OpenAction() { 
        setEnabled(
false ); 
    } 
     
    public 
void  run() { 
        
for  (Iterator iter  =  selection.iterator(); iter.hasNext();) { 
            IInstance ins 
=  (IInstance) iter.next(); 
            
try  { 
                
// TODO Only in windows can do this.  
                Runtime.getRuntime().exec( " cmd /E:ON /c start  "   +  ins.getReferenceURL()); 
            } 
catch  (IOException e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
 
    public 
void  selectionChanged(SelectionChangedEvent event) { 
        selection 
=  (IStructuredSelection) event.getSelection(); 
        setEnabled(selection.size() 
>   0 ); 
    } 
 
    public String getText() { 
        
return   " &Open in browser "
    } 
}

上面是一个例子IAction,它的作用是在触发时将用户选中的条目在浏览器里打开。这个类同时还实现了ISelectionChangeAction,这样就可以在用户没有选中任何条目的时候将自己变为不可用。当然,你要把它作为监听器加入某个列表对象的监听器列表,像下面代码里这样:

private  void  createActions() { 
    openAction 
=   new  OpenAction(); 
    removeAction 
=   new  RemoveAction(tvResult); 
    reloadAction 
=   new  ReloadAction(tvResult); 
    tvResult.addSelectionChangedListener(openAction); 
    tvResult.addSelectionChangedListener(removeAction); 
    tvResult.addSelectionChangedListener(reloadAction); 

注意,最后的三句就是加入监听列表的功能。有些IAction需要改变所监听对象(比如一个TableViewer)的行为,所以要把那个对象作为参数传递给它才行。下面是把IAction对象加入菜单的代码:

private  void  createMenu() { 
    IMenuManager mgr 
=  getViewSite().getActionBars().getMenuManager(); 
    mgr.add(openAction); 
    mgr.add(removeAction); 
    mgr.add(reloadAction); 

把IAction对象加到工具条的代码几乎完全一样,只是第一句有所不同:

private  void  createMenu() { 
    IToolBarManager mgr 
=  getViewSite().getActionBars().getToolBarManager(); 
    mgr.add(openAction); 
    mgr.add(removeAction); 
    mgr.add(reloadAction); 

上下文菜单就显得有些麻烦了,因为View并没有一个“PopupMenuManager”这样的东西,所以我们只能半手动的来建立:

private  void  createContextMenu() { 
    MenuManager mgr 
=   new  MenuManager(); 
    mgr.setRemoveAllWhenShown(
true ); 
    mgr.addMenuListener(
new  IMenuListener() { 
        public 
void  menuAboutToShow(IMenuManager manager) { 
            fillContextMenu(manager); 
        } 
    }); 
    Menu menu 
=  mgr.createContextMenu(tvResult.getControl()); 
    tvResult.getControl().setMenu(menu); 
    getSite().registerContextMenu(mgr, tvResult); 
}

这个MenuManager和我们在createMenu()里通过getMenuManager()得到的是同一个类(但不是同一个实例哦),setRemoveAllWhenShown(true)的作用是清空以前显示的菜单项,当触发了menu事件时,重新填充(fillContextMenu),所以如果你不把removeAllWhenShow置为true的话,每点一下右键你就会看到菜单项多出一倍来。Menu是swt的控件(刚才说的MenuManager、ToolbarManager都是jface里的东西,jface给swt包了一层),用MenuManager可以创建出一个Menu对象,然后我们用表格的setMenu方法将表格控件与Menu控件联系在一起就好了。

最后还有一句,它是为扩展这个上下文菜单用的,例如你可以在plugin.xml里统一指定给某种类型的元素都加上某个菜单项(例如,如果用户选中了一个.zip文件,会多出一个“解压缩”选项)。那么新加的菜单项会出现在上下文菜单的哪里呢,最上方还是最下方,还是……?所以呢,要在fillContextMenu的时候指定一下:

protected  void  fillContextMenu(IMenuManager manager) { 
    manager.add(openAction); 
    manager.add(removeAction); 
    manager.add(reloadAction); 
    manager.add(
new  GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); 
 
}

前三句都没什么特别,最后一句就是指定了上面我们说的这个“增加点”,这样,你想让后来的菜单放在哪里都行了。

最后,Eclipse的Workbench提供了一些比较通用的系统菜单项,如下:

public static final String [] GLOBAL_ACTIONS  =  { 
        UNDO, 
        REDO, 
        CUT, 
        COPY, 
        PASTE, 
        PRINT, 
     DELETE, 
        FIND, 
     SELECT_ALL, 
        BOOKMARK 
}; 

当你的焦点在不同的View或Editor里时,同一个系统菜单项会有不同的作用产生。例如在文本编辑器中delete项是删除当前选中的文字,而在你的视图里,你希望delete的作用是删除用户选中的表格条目,刚好是removeAction的功能。所以你要把你的IAction对象和系统菜单挂在一起:

private  void  hookGlobalActions() {
      IActionBars bars = getViewSite().getActionBars(); 
      bars.setGlobalActionHandler(IWorkbenchActionConstants.DELETE, removeAction); 

注意,要选择语义上比较相近的系统菜单项来挂接,否则会造成用户的困扰。比如你非要把COPY实现为openAction,当用户在系统菜单里选了copy命令,本以为会把当前选中的条目复制到剪贴板,你却给人家打开了这些条目,多滑稽。

好了,菜单方面基本上就这些内容。可以看出,Eclipse的Workbench的确为我们提供了很多方便,特别是如果能够灵活利用plugin来进行定义,不仅可以节约大量的代码,还能让我们始终保持对系统的掌握。所以说,RCP的风行可不是没有道理哦。

本文转自博客园八进制的博客,原文链接:给Eclipse插件的View加上菜单和工具条,如需转载请自行联系原博主。

相关文章
|
6月前
|
Java Maven Android开发
在Eclipse里配置Maven插件
Maven是一款比较常用的Java开发拓展包,它相当于一个全自动jar包管理器,会导入用户开发时需要使用的相应jar包。使用Maven开发Java程序,可以极大提升开发者的开发效率。下面我就跟大家介绍一下如何在Eclipse里安装和配置Maven插件。
148 0
|
4天前
|
Java Android开发
Eclipse 菜单
Eclipse 菜单
7 0
Eclipse 菜单
|
6月前
|
XML Java Maven
eclipse 、idea 安装activiti插件
eclipse 、idea 安装activiti插件
155 0
|
6月前
|
Android开发
Eclipse工具使用技巧
Eclipse工具使用技巧
|
11月前
|
Java Android开发
eclipse安装SpringBoot插件的无敌办法
eclipse安装SpringBoot插件的无敌办法
130 0
|
11月前
|
Java Android开发 Spring
在 Eclipse 中安装 SpringTools 插件
在 Eclipse 中安装 SpringTools 插件
127 0
|
XML Java 应用服务中间件
Eclipse插件下载地址汇总
Eclipse插件下载地址汇总
305 0
|
存储 Android开发
Eclipse安装Flowable Eclipse Designer插件实现图形建模BPMN 2.0流程图
Eclipse安装Flowable Eclipse Designer插件实现图形建模BPMN 2.0流程图
381 0
|
IDE NoSQL Java
Eclipse下载安装和JDK下载安装(环境配置)及下载C++插件CDT
Eclipse下载安装和JDK下载安装(环境配置)及下载C++插件CDT
374 0