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加上菜单和工具条相关推荐

  1. [Eclipse]GEF入门系列(六、添加菜单和工具条)

    我发现一旦稍稍体会到GEF的妙处,就会很自然的被它吸引住.不仅是因为用它做出的图形界面好看,更重要的是,UI中最复杂和细微的问题,在GEF的设计中无不被周到的考虑并以适当的模式解决,当你了解了这些,完 ...

  2. 菜单与工具条的同步 APP_STANDARD.SYNCHRONIZE

    初始情况下,菜单与工具条的状态是一致的,但程序中动态改变某一属性时,工具条并不能相应地改变,所以必须编写代码完成同步. 通过调用以下函数来完成同步: APP_STANDARD.SYNCHRONIZE ...

  3. 【转载】在ARX中通过COM在ACAD中添加菜单和工具条

    科技创新项目需要结题了,现在只有一个标注剪切的功能,同张老师商量了一下,张老师叫我再加上一两个功能,同时要做出有对话框.菜单或者工具条之类的UI界面.刚好碰巧当天晚上就看到有人在二次开发群里讲添加菜单 ...

  4. 菜单和工具条---QT

    这一节我们谈一谈用QT怎么做一个简单的菜单和工具条!以后的讲解中我就在代码的后面加上注释,我想这样可能是比较清晰一点,这也符合我的编程习惯!好吧,就这样吧,呵呵! 开始了,先创建工程,注意的是你在选择 ...

  5. c-free 5.0 菜单,工具条丢失解决

    刚开始提起学习c语言的劲头,发现c-free挺好用,适合新手.谁知道今天早上一打开出现了一个窝心事:菜单和工具条全部不见了 用快捷键打开一个源代码,F5也能运行.想着程序没有被破坏,可能被隐藏了,点了 ...

  6. Eclipse插件TPTP-程序Profile与分析工具详细教程

    TPTP简介 Eclipse Test & Performance Tools Platform 是Eclipse的一个顶级工程(Top-Level Project),TPTP项目封装了一大堆 ...

  7. qt 工具栏显示图标和文字_菜单和工具条上图标显示不了,为什么?

    原文:http://www.360doc.com/content/12/0427/11/6828497_206883958.shtml 1.QT creator 中File--new-QT resou ...

  8. 如何关闭Eclipse的面包屑(breadcrumb)工具条

    1. 在工具栏上找"Toggle Breadcrumb"按钮,单击使其恢复未选中状态即可 2. 如果找不到这个按钮.通过菜单"Window->Customize P ...

  9. 在ARX中通过COM在ACAD中添加菜单和工具条

    转载地址:http://blog.csdn.net/habit2/article/details/438318 代码如下: extern "C" AcRx::AppRetCode  ...

最新文章

  1. linux 用户java_linux之用户管理
  2. 怎么让wordpress用sqlite3 搭建轻量级博客系统
  3. Druid 配置_LogFilter
  4. 五、CPU详解、寄存器详解、标志寄存器详解
  5. php与sql server,PHP和SQL Server – 思考
  6. 拓端tecdat|python研究汽车传感器数据统计可视化分析
  7. [2018.03.14 T1] 矩阵(matrix)
  8. i3wm开启自动设置显示器顺序方向分辨率
  9. 2019第十二届“认证杯”数学建模(第一阶段)
  10. 证件OCR识别360度全面解析
  11. java string通配符_java通配符
  12. 【汽车总线技术】CAN FD与CAN网络共存的解决方案
  13. CRM系统概念与项目开发流程
  14. 侍魂微信第一个服务器,在游戏中,武者大大们来到的第一个地图叫什么名字?...
  15. 【小程序】开发需要注意的地方(一)
  16. 8、iOS strip 与 dead strip
  17. 三维激光扫描技术的应用领域有哪些?
  18. hadoop 四种压缩格式
  19. 汪国真的八字命理分析
  20. 如果在天堂遇见你,你还记不记得我是谁?

热门文章

  1. 项目中遇到一些实用/优秀的代码写法(杂烩)
  2. PHP Web Shell in browser
  3. 猫都能学会的Unity3D Shader入门指南(一)
  4. ubuntu 部署 redis 主从节点配置
  5. MySQL/MariaDB Tips
  6. python-PyQuery详解
  7. MYSQL学习笔记2--mysql 静态和动态plugin
  8. 关于SQL语言的优化(Oracle)
  9. 浅谈 voip 未來企業通信
  10. 与技术无关,犯错了,希望大家帮下