我期望在popupmenu上添加一个菜单,菜单的名称叫Huayusoft;这个菜单有一个菜单项,菜单项的名称叫Falcon Jar;
我该怎么做呢?
Eclipse提供了三种命令与操作的方式;
一种叫ActionSets;一种叫Command;一种叫popupmenus;
ActionSets方式使用的是扩展点org.eclipse.ui.actionsets;
Command方式使用了三个扩展点:org.eclipse.ui.menus; org.eclipse.ui.commands;org.eclipse.ui.handlers;
popupmenus方式使用了一个扩展点:org.eclipse.ui.popupmenus;
在plugin.xml中会做什么呢?在plugin.xml中,有三大任务:定义;响应;连接。
定义是指Command、Action、Category、Menu等的定义;比如Command、Action、Category的定义一般有三个要素:ID、Label和Description;Menu的定义一般有两个要素:ID和Label;
响应是对Command、Action的处理:一般都是ID对应Class。
连接是各个定义之间的关系。比如某个Command属于哪个Category或者Menu;在什么位置。这种连接都是通过ID实现的。
以Command方式为例:
在org.eclipse.ui.commands扩展点中,对command和category进行了定义,并建立了command到category的连接;
在org.eclipse.ui.menus扩展点中,对menu进行了定义,并建立了menu到command的连接;并指定了command在menu中的位置;
此外,还需要制定menu的位置;于是有了menuContribution元素和locationURI属性;locationURI属性制定了menu的位置。
例如:menu:org.eclipse.ui.main.menu表示主菜单;menu:help表示help菜单;而popup:org.eclipse.ui.popup.any表示popup菜单。
修改好plugin.xml后,我想要的效果就初步达到了。但是,这还不够。FatJar插件会根据选中的对象来决定是否将菜单项添加到popupmenu上。如果当前选中的是一个project,就出现Fat Jar;如果是一个File或者一个Folder,就不会出现。我也需要这个功能。当选中的不是一个Java project时,我希望我的菜单不要出现。
Eclipse提供了对这个需求的支持,就是,在plugin.xml中,添加条件判断,只有当特定的条件满足时,菜单才会出现。
在这个条件判断中,可以选择变量:例如:with variable=selection;后面有一些表达式,它们每个值都是true或者false;表达式之间用and或者or,最后得到一个结果;选择的变量可能是一个集合,于是,还有遍历:iterate;于是,有集合中每一项结果之间的操作:operator=or;还有,当集合为空时,应该返回何值:ifEmpty;
最后的结果决定了是显示还是隐藏。
这个条件表达式是和command还是menu对应的呢?很显然,是与command对应的。显示还是隐藏的主体是command。我不知道Eclipse有没有支持对menu的条件表达式,但是,有一点很清楚。当menu中的所有command都隐藏时,那么,这个menu必然隐藏。这种关系是合理的。
我的条件表达式用的variable是selection;在例子中,我看到有两个子表达式,一个是instanceof value=”org.eclipse.core.resource.IResource”;一个是instanceof value=”org.eclipse.jdt.core.IJavaElement”。两个表达式用or。即只要选中的对象属于其中一个就是了。
我本来以为选中的project是属于IResource的,因为,前一篇有说过,Eclipse runtime core上面有一部分是Resource;这是一个插件,所有的workspace、project甚至文件都是属于Resource;后来,我发现我错了。我选中的项目或者文件是instanceof org.ecilpse.jdt.core.IJavaElement的。
看了IJavaElement的定义,这是一个非常核心的接口。它是JavaModel描述所有Java相关对象的基础。它有很多的子接口:IJavaProject代表了Java项目;IClassFile代表了类文件;而IField代表了域;IAnnotation代表了注解。
由于Eclipse是可以支持多种项目的;例如C++项目、C#项目、Java项目。因此,真相大白了。我终于理解了JDT的含义。JDT全称是Java Development Toolkit;它的本质就是一个Java插件。这就是它们属于org.eclipse.jdt.core这个包,而不是org.eclipse.core包的根本原因了。
添加条件表达式,将条件改为org.eclipse.jdt.core.IJavaProject,我实现了只有在选中Java Project时,才会显示菜单。而在选中文件或者文件夹时,不会显示菜单。
我发现EclipseMe在选中Java Project和J2ME Project时,会有不同的菜单项:如果是J2ME Project,菜单项是create J2me midlet suit;而如果是Java Project,菜单项则是converto to J2ME midlet suit。我也需要这个功能,当选中后,我要判断,当前选中的项目是J2ME项目还是其它项目。可是,我怎么才能判断当前选中的项目是J2ME的项目呢?很显然,Eclipse是不具备这个功能的。J2ME相关的都是由EclipseMe插件来实现的。因此,我需要去EclipseMe中去找,看有没有相关的接口提供。(见开发笔记三)
几个问题:
1. Command的条件判断什么会执行?
很显然,在每次popup menu弹出前,会执行这个条件判断,确定是否显示command和menu。
2. Eclipse会怎么处理plugin.xml?插件什么时候会被激活?
既然,每次popup menu弹出前,都需要执行这个条件判断;而这个条件判断又是放在plugin.xml中的,那么,就有必要将plugin.xml放到内存中了,不然的话,就需要每次弹出菜单时,都需要读取文件,这肯定是不合理的。
Eclipse在启动的时候,会读取plugin目录下的每一个MANIFEST.MF和plugin.xml,并生成一个对应的内存结构。这句话和我上面的判断是一致的。
但是,这个时候,插件是没有导入的。很显然,Eclipse设计了一套规则确定插件何时被导入,核心的一点是除非主动地去使用,否则不会导入。
因此,弹出popupmenu,条件判断,对应的插件不会被导入。
这也为我使用EclipseMe插件提供了思路。很显然,我要判断项目是否是j2me的项目,这个工作也是在plugin.xml中的。我如何使用EcipseMe插件呢?很显然,EclipseMe会提供类名,我只要判断选中的是否是J2ME的项目就OK了。当条件判断使用了类名的时候,Eclipseme插件会否导入呢?