例如,新建,打开,删除,剪切,粘帖等等,这些命令通常出现在窗口的菜单和工具栏上
但是,在不同的情况下可能执行不同的操作。
开发这些功能的时候,我们通常无法预料未来将出想哪些新的需求。
所以,这些动能应当随着当前的活动的某些部件的而改变。好的实现方式是把这些功能实现的职责交给对应的部件。
如下图:
新建的按钮在当前激活的视图为“项目”视图时,应当是新建项目,如果是在文档视图中时,就应当是新建文档,同样删除的按钮也是一样的。
接下来我记录了我的实现方法:
1. 在创建窗口菜单和工具栏的类ApplicationActionBarAdvisor中:
// 保存
saveAction = ActionFactory.SAVE.create(window);
register(saveAction);
// 保存全部
saveAllAction = ActionFactory.SAVE_ALL.create(window);
register(saveAllAction);
// 保存全部
saveAsAction = ActionFactory.SAVE_AS.create(window);
register(saveAsAction);
// 关闭
closeAction = ActionFactory.CLOSE.create(window);
register(closeAction);
// 关闭全部
closeAllAction = ActionFactory.CLOSE_ALL.create(window);
register(closeAllAction);
reOpenList = ContributionItemFactory.REOPEN_EDITORS.create(window);
// 退出系统
exitAction = ActionFactory.QUIT.create(window);
register(exitAction);
// 编辑菜单
redoAction = ActionFactory.REDO.create(window);
register(redoAction);
undoAction = ActionFactory.UNDO.create(window);
register(undoAction);
cutAction = ActionFactory.CUT.create(window);
register(cutAction);
copyAction = ActionFactory.COPY.create(window);
register(copyAction);
pasteAction = ActionFactory.PASTE.create(window);
register(pasteAction);
deleteAction = ActionFactory.DELETE.create(window);
register(deleteAction);
// 窗口
openNewWindowAction = ActionFactory.OPEN_NEW_WINDOW.create(window);
register(openNewWindowAction);
editActionSetAction = ActionFactory.EDIT_ACTION_SETS.create(window);
register(editActionSetAction);
savePerspectiveAction = ActionFactory.SAVE_PERSPECTIVE.create(window);
register(savePerspectiveAction);
closePerspectiveAction = ActionFactory.CLOSE_PERSPECTIVE.create(window);
register(closePerspectiveAction);
closeAllPerspectiveAction = ActionFactory.CLOSE_ALL_PERSPECTIVES
.create(window);
register(closePerspectiveAction);
resetPerspectiveAction = ActionFactory.RESET_PERSPECTIVE.create(window);
register(resetPerspectiveAction);
preferenceAction = ActionFactory.PREFERENCES.create(window);
register(preferenceAction);
// 关于
helpContentAction = ActionFactory.HELP_CONTENTS.create(window);
register(helpContentAction);
helpSearchAction = ActionFactory.HELP_SEARCH.create(window);
register(helpSearchAction);
helpDynamicAction = ActionFactory.DYNAMIC_HELP.create(window);
register(helpDynamicAction);
aboutAction = ActionFactory.ABOUT.create(window);
register(aboutAction);
}
这里有很多种方式创建系统的菜单,我只写两种。上面的一种是用程序写,例如:saveAction = ActionFactory.SAVE.create(window);
然后,把这些Action加入到菜单中:
MenuManager systemMenu = new MenuManager( " 开始(&S) " , UIConstants.M_SYSTEM);
MenuManager editMenu = new MenuManager( " 编辑(&E) " , UIConstants.M_EDIT);
MenuManager navigateMenu = new MenuManager( " 导航(&V) " ,
UIConstants.M_NAVIGATOR);
MenuManager searchMenu = new MenuManager( " 查询(&A) " , UIConstants.M_SEARCH);
MenuManager windowMenu = new MenuManager( " 窗口(&W) " ,
IWorkbenchActionConstants.M_WINDOW);
MenuManager helpMenu = new MenuManager( " 帮助(&H) " ,
IWorkbenchActionConstants.M_HELP);
menuBar.add(systemMenu);
menuBar.add(editMenu);
menuBar.add(navigateMenu);
menuBar.add(searchMenu);
menuBar.add( new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
menuBar.add(windowMenu);
menuBar.add(helpMenu);
systemMenu.add( new GroupMarker( " intellifmea " ));
systemMenu.add( new Separator(UIConstants.MB_RELOADOBJECT));
systemMenu.add(saveAction);
systemMenu.add(saveAllAction);
systemMenu.add(saveAsAction);
systemMenu.add( new Separator());
systemMenu.add(closeAction);
systemMenu.add(closeAllAction);
systemMenu.add( new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
systemMenu.add(reOpenList);
systemMenu.add( new Separator( " blank " ));
systemMenu.add(exitAction);
editMenu.add(undoAction);
editMenu.add(redoAction);
editMenu.add( new Separator());
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.add(pasteAction);
editMenu.add(deleteAction);
editMenu.add( new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
navigateMenu
.add( new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
windowMenu.add(openNewWindowAction);
windowMenu.add( new Separator());
windowMenu.add(editActionSetAction);
windowMenu.add(savePerspectiveAction);
windowMenu.add(resetPerspectiveAction);
windowMenu.add(closePerspectiveAction);
windowMenu.add(closeAllPerspectiveAction);
windowMenu.add( new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
windowMenu.add(preferenceAction);
searchMenu.add( new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
helpMenu.add(helpContentAction);
helpMenu.add(helpSearchAction);
helpMenu.add(helpDynamicAction);
helpMenu.add(aboutAction);
}
第二种方法是直接在Plugins.xml上扩展
locationURI = " menu:com.sg.hyperobject.ui.systemmenu?after=intellifmea " >
< command
commandId = " com.sg.intellifmea.commands.CreateProjectWiz "
disabledIcon = " icons/newobject_dis.gif "
icon = " icons/newobject.gif "
label = " 新建(&N)... "
style = " push "
tooltip = " 创建一个新项目 " >
</ command >
< command
commandId = " com.sg.intellifmea.commands.Open "
icon = " icons/Open.gif "
label = " 打开(&O)... "
tooltip = " 打开 " >
</ command >
</ menuContribution >
请注意locationURI="menu:com.sg.hyperobject.ui.systemmenu?after=intellifmea"指定了这个菜单应当出现的位置是在intellifmea之后的。intellifmea是什么呢?
请看上文中我们为systemMenu留出的扩展菜单的一个GroupMarker,(在fillMenuBar方法中 ) systemMenu.add(new GroupMarker("intellifmea"));
这样,pluins.xml中定义的菜单就加在了指定的位置了(这种扩展同样适用于扩展各种各样的工具栏和菜单,例如视图的菜单工具栏以及右键菜单)
2. 为菜单指定Command
point ="org.eclipse.ui.commands" >
< category
id ="com.sg.intellifmea.project"
name ="intellifmea project" >
</ category >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.CreateProjectWiz"
name ="CreateProjectWiz" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.Open"
name ="OpenProject" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.ProjectProcess"
name ="ProjectProcess" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.ProjectPause"
name ="ProjectPause" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.ProjectFinish"
name ="ProjectFinish" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.ProjectCancel"
name ="ProjectCancel" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.ProjectViewerReload"
name ="ProjectViewerReload" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.SetCurrentProject"
name ="SetCurrentProject" >
</ command >
< command
categoryId ="com.sg.intellifmea.project"
id ="com.sg.intellifmea.commands.CreateDocument"
name ="CreateDocument" >
</ command >
</ extension >
扩展org.eclipse.commands扩展点
3. 为command指定Handler
扩展 "org.eclipse.ui.handlers"
这里可以指定commands的调用时执行的方法,可以控制该command的是否可用。当然这里还涉及到一个系统性的知识。包括了表达式,选择等等,这里不详述。
point ="org.eclipse.ui.handlers" >
< handler
class ="com.sg.intellifmea.commands.CreateProjectWiz"
commandId ="com.sg.intellifmea.commands.CreateProjectWiz" >
</ handler >
< handler
class ="com.sg.intellifmea.commands.Open"
commandId ="com.sg.intellifmea.commands.Open" >
< enabledWhen >
< count
value ="1" >
</ count >
</ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.ProjectProcess"
commandId ="com.sg.intellifmea.commands.ProjectProcess" >
< activeWhen >
< count
value ="1" >
</ count >
</ activeWhen >
< enabledWhen >
< iterate
ifEmpty ="false" >
< test
args ="进行"
property ="com.sg.intellifmea.tester.ProjectStatusChangeableTest" >
</ test >
</ iterate ></ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.ProjectPause"
commandId ="com.sg.intellifmea.commands.ProjectPause" >
< activeWhen >
< count
value ="1" >
</ count >
</ activeWhen >
< enabledWhen >
< iterate
ifEmpty ="false" >
< test
args ="暂停"
property ="com.sg.intellifmea.tester.ProjectStatusChangeableTest" >
</ test >
</ iterate >
</ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.ProjectFinish"
commandId ="com.sg.intellifmea.commands.ProjectFinish" >
< activeWhen >
< count
value ="1" >
</ count >
</ activeWhen >
< enabledWhen >
< iterate
ifEmpty ="false" >
< test
args ="完成"
property ="com.sg.intellifmea.tester.ProjectStatusChangeableTest" >
</ test >
</ iterate >
</ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.ProjectCancel"
commandId ="com.sg.intellifmea.commands.ProjectCancel" >
< activeWhen >
< count
value ="1" >
</ count >
</ activeWhen >
< enabledWhen >
< iterate
ifEmpty ="false" >
< test
args ="取消"
property ="com.sg.intellifmea.tester.ProjectStatusChangeableTest" >
</ test >
</ iterate >
</ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.ProjectViewerReload"
commandId ="com.sg.intellifmea.commands.ProjectViewerReload" >
</ handler >
< handler
class ="com.sg.intellifmea.commands.SetCurrentProject"
commandId ="com.sg.intellifmea.commands.SetCurrentProject" >
< activeWhen >
< count
value ="1" >
</ count >
</ activeWhen >
< enabledWhen >
< iterate
ifEmpty ="false" >
< and >
< test
args ="工作"
property ="com.sg.intellifmea.tester.ProjectStatusChangeableTest" >
</ test >
< not >
< test
property ="com.sg.intellifmea.tester.IsWorkingProject" >
</ test >
</ not >
</ and >
</ iterate >
</ enabledWhen >
</ handler >
< handler
class ="com.sg.intellifmea.commands.CreateDocument"
commandId ="com.sg.intellifmea.commands.CreateDocument" >
< activeWhen >
< with
variable ="activePartId" >
< equals
value ="com.sg.intellifmea.view.ProjectView" >
</ equals >
</ with >
</ activeWhen >
< enabledWhen >
< count
value ="1" >
</ count >
</ enabledWhen >
</ handler >
</ extension >
4. 指定键盘的快捷键
扩展org.eclipse.ui.bindings设置快捷键,以下是例子
point ="org.eclipse.ui.bindings" >
< key
commandId ="com.sg.hyperobject.commands.dataobject.OpenObject"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+O" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.dataobject.MakeWipDTO"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M2+F2" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.dataobject.DeleteDTO"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M2+DEL" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.dataobject.CopySelectionDTO"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+M2+T" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.search.FindInResult"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+F3" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.search.FindInResultNext"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="F3" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.InsertItem"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+I" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.AppendItem"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+A" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.MoveUp"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+ARROW_UP" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.MoveDown"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+ARROW_DOWN" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.LinkItem"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+L" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.ui.HideAssistant"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+H" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.CopyItem"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+M2+C" >
</ key >
< key
commandId ="com.sg.hyperobject.commands.tableediting.PasteItem"
contextId ="org.eclipse.ui.contexts.window"
schemeId ="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence ="M1+M2+P" >
</ key >
</ extension >
到此为止,我们基于Plugins.xml实现了菜单。
5. 不同的部件中具有不同的功能的全局菜单和工具栏
我们只需要在该部件中加入以下代码,这个id的菜单功能就被替换了。
奇怪的是,似乎这个替换并不需要我们主动地在侦听激活或者非激活状态。也无需我们主动地clear
getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);
我们在创建文档视图的方法中,加上上面的一句话,那么在文档视图中,点击删除按钮,deleteAction就被执行了
同样,我们在创建项目视图的方法中, 加上上面的一句话,那么在项目视图中,点击删除按钮,项目视图的deleteAction就被执行了,而不是执行的文档视图的删除方法。