org.eclipse.ui.menus
locationURI
MenuContribution locationURI = “[Scheme]:[id]?[argument-list]”
1.menu or toolbar
2. problem view
popup:org.eclipse.ui.views.ProblemView?after=
org.eclipse.ui.main.menu?after=
org.eclipse.search.menu?dialogGroup
org.eclipse.ui.popupMenus
popup:org.eclipse.ui.views.ProblemView?after=additions
popup:org.eclipse.ui.popup.any?after=additions
steps:
1.extension from menus
2.the menu location in where
location url
How do you find the locationURI of menu contributions?
If you use ALT+SHIFT+F1
on the view, it will list the IDs of registered context menus
http://www.eclipse.org/pde/incubator/spy/
Tip: Subclass AbstractHandler rather than implementing IHandler.
menu ‘s handler
import org.eclipse.core.commands.AbstractHandler;
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
MessageDialog.openInformation(
window.getShell(),
"Demo",
"Hello, Eclipse world");
操作步骤:
1. 添加org.eclipse.ui.commands扩展,创建一个command
2. 添加org.eclipse.ui.menus扩展,创建一个menuContribution
3. 添加org.eclipse.ui.handlers扩展,创建一个handler,command id指向步骤1中创建的command,并为其编写实现类
4. 为步骤3中创建的handler指定激活状态的表达式
要点:
1.
Q:新建command时,是否需要为其指定catagory属性?
A:看情况。我个人感觉catagory就是用来进行菜单分组的。例如,一般一个插件会把自己提供的菜单指定一个统一的catagory,这样在显示或处理时能放在一起
2.
Q:新建command时,是否需要为其指定name属性?
A:name属性是必填项,当然要指定了 :-) 当对应的menu没有指定label时,菜单中显示的就是这个name了。
3.
Q:menu的locationURI如何指定?
A:这是我碰到的第一个难题,因为uri需要用一个描述脚本编写,那么如何编写脚本?编写脚本的规则是什么? 答案就在eclipse的帮助文档中: http://help.eclipse.org/stable/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_cmd_menus.htm
举例:popup:org.eclipse.debug.ui.DebugView?after=additions
可以把这个示例uri看成3部分,第一部分是“popup”,代表样式是右键弹出菜单;第二部分是 “org.eclipse.debug.ui.DebugView”,含义是显示在哪个view的弹出菜单中;第三部分是 “after=additions”,含义是显示在弹出菜单的什么位置(弹出菜单中还有其他的菜单项)。
这个只是uri众多写法的其中之一,还有向主菜单添加项目的,向工具栏添加项目的,具体情况请参考上面的帮助文档链接。
进行到这里,菜单应该已经可以在debug窗口中显示出来了,但是这又引发了一个问题:每当点击这个菜单的时候,总是报告:The chosen operation is not enabled。这是因为handler的实现类直接实现了IHandler接口,其isHandled,isEnabled方法由eclipse自动生成的情况下全部是返回false的,除非必要,否则一般情况下应采用继承org.eclipse.core.commands.AbstractHandler的方式来编写handler的实现类,可以省去不少麻烦。
其中要注意的是:在plugin编辑器中,点击handler的属性面板中的“class”链接,会自动创建实现类,这个自动创建的实现类不是继承AbstractHandler的,而是直接实现IHandler,我就是这样被带到沟里去的。
报错的问题解决了,但是发现新增的菜单在有选中堆栈和没有选中堆栈的情况下都可以显示,这个有些不大合适,因为如果要复制堆栈信息,至少应该有一条被选中才可以。所以应该采取措施让这个菜单在没有选中任何堆栈信息时灰显,这也就引出了另一个很难理解的框架:command core expression。
command core expression是一个脚本规则,eclipse定义了许多变量、属性,通过core expression可以对这些变量、属性进行诸如instanceof, equals等判定,从而得到一个boolean值用来参与程序的逻辑。针对这个问题,我们只需要为handler指定enabledWhen的表达式(core expression),让handler只在选中已条堆栈信息时才被激活即可。
core expression的文档在:http://wiki.eclipse.org/Command_Core_Expressions 在 org.eclipse.ui.handlers 扩展的声明文档中也有很多可以参考的信息。
在本例中我们通过对selection变量的计数来判断是否有堆栈信息被选定。详细内容请参考本文后面的plugin.xml文件的内容。
至此,添加菜单的过程就结束了,看似简单,其实牵涉了许多其他的应用技术,例如core expression, locationURI等。其他的问题其实也是一样,不断地遇到问题,不断地踩平它,不断地积累,慢慢地,一条路就会出现在脚下。