Retarget Action
这是一种具有一定语义但没有实际功能的Action,它唯一的作用就是在主菜单条或主工具条上占据一个项位置,编辑器可以将具有实际功能的Action映射到某个Retarget Action,当这个编辑器被激活时,主菜单/工具条上的那个Retarget Action就会具有那个Action的功能。举例来说,Eclipse提供了IWorkbenchActionConstants.COPY这个Retarget Action,它的文字和图标都是预先定义好的,假设我们的编辑器需要一个"复制节点到剪贴板"功能,因为"复制节点"和"复制"这两个词的语义十分相近,所以可以新建一个具有实际功能的
CopyNodeAction(extends Action),然后在适当的位置调用下面代码实现二者的映射:
IActionBars.setGlobalActionHandler(IWorkbenchActionConstants.COPY,copyNodeAction)
当这个编辑器被激活时,Eclipse会检查到这个映射,让COPY项变为可用状态,并且当用户按下它时去执行CopyNodeAction里定义的操作,即run()方法里的代码。
Eclipse引入Retarget Action的目的是为了尽量减少主菜单/工具条的重建消耗,并且有利于用户使用上的一致性。在GEF应用程序里,因为很可能存在多个视图(例如编辑视图和大纲视图,即使暂时只有一个视图,也要考虑到以后扩展为多个的可能),而每个视图都应该能够完成相类似的操作,例如在树结构的大纲视图里也应该像编辑视图一样可以删除选中节点,所以一般的操作都应以映射到Retarget Action的方式建立。
我们不仅可以使用Eclipse平台内置的Retarget Action,比如ActionFactory.CUT,ActionFactory.COPY,ActionFactory.PASTE等。
也可以定义自己的Retarget Action,只需要继承org.eclipse.ui.actions.RetargetAciton即可。例如:
以下代码来自开源RCP应用eclipsetrader。
package net.sourceforge.eclipsetrader;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.RetargetAction;
//继承自RetargetAction
public class SettingsAction extends RetargetAction
{
public SettingsAction(IWorkbenchWindow window)
{
super("settings", "Settings...");//前者为id,后者为显示文本
window.getPartService().addPartListener(this);
setActionDefinitionId("org.eclipse.ui.edit.settings"); //主要为快捷键设置作准备
}
}
1.在ApplicationActionBar的makeActions方法中,创建Retarget Action。
settingsAction = new SettingsAction(window);
registger(settingsAction);
2.在fillMenuBar中这样用:
menu.add(settingsAction);
3.在需要使用RetargetAction的视图或者编辑器,这样用,如在某视图的createPartControl方法中这样使:
IActionBars actionBars = getViewSite().getActionBars();
actionBars.setGlobalActionHandler("cut", cutAction);
actionBars.setGlobalActionHandler("copy", copyAction);
actionBars.setGlobalActionHandler("paste", pasteAction = new PasteAction(this));
actionBars.setGlobalActionHandler("delete", deleteAction);
actionBars.setGlobalActionHandler("settings", new Action() {//重点看这里
public void run()
{
WatchlistSettingsDialog dlg = new WatchlistSettingsDialog(getWatchlist(), getViewSite().getShell());
dlg.open();
}
});