我们知道,RetargetAction是一个UI占位符,只提供了最简单的诸如id,image,tooltip等信息,真实的Action可以
动态的绑定,详细内容在以前的博文中已有论述(在Eclipse开发中使用Retarget Action ),今天主要是分析一下其基本原理,和IPartListener接口有关(参见IPartListener与IPartListener2[总结] ).
先看一下org.eclipse.ui.actions.RetargetAction的声明(限于篇幅,只列出和本议题有关的代码):
public class RetargetAction extends PartEventAction implements
ActionFactory.IWorkbenchAction {
//最终绑定的Action
private IAction handler;
public void partActivated(IWorkbenchPart part) {
super.partActivated(part);
IWorkbenchPartSite site = part.getSite();
//获取ActionBar
SubActionBars bars = (SubActionBars) ((PartSite) site).getActionBars();
bars.addPropertyChangeListener(propertyChangeListener);
//根据key从bars中取得相应的Action赋值给handler
setActionHandler(bars.getGlobalActionHandler(getId()));
}
....其它代码暂略...
/**
* Invoked when an action occurs.
* 真实运行的action
*/
public void run() {
if (handler != null) {
handler.run();
}
}
}
再看下其父类PartEventAction.
/**
* The abstract superclass for actions that listen to part activation and
* open/close events. This implementation tracks the active part (see
* <code>getActivePart</code>) and provides a convenient place to monitor
* part lifecycle events that could affect the availability of the action.
* 此类监听着WorkbenchPart(视图或编辑器)的激活,打开和关闭事件,主要是为了定位
* Workbench中当前激活的WorkbenchPart
* <p>
*/
public abstract class PartEventAction extends Action implements IPartListener {
//当前激活的WorkbenchPart
private IWorkbenchPart activePart;
//返回Workbench中当前激活的WorkbenchPart
public IWorkbenchPart getActivePart() {
return activePart;
}
//当有WorkbenchPart激活时,为activePart赋值
public void partActivated(IWorkbenchPart part) {
activePart = part;
}
/**
* 如果当前关闭的WorkbenchPart恰好为activePart,则置为null
*/
public void partClosed(IWorkbenchPart part) {
if (part == activePart) {
activePart = null;
}
}
/**
* 当某WorkbenchPart非激活状态时,将activePart置为null
*/
public void partDeactivated(IWorkbenchPart part) {
activePart = null;
}
}
我们再看一下,在WorkbenchPart中我们是怎么将要绑定的Actoin是怎样以key/value的形式设置到IActionBars中的.
eg:
在需要使用RetargetAction的视图或者编辑器,这样用,如在某视图的createPartControl方法中这样使:
IActionBars actionBars = getViewSite().getActionBars();
IAction cutAction = ...;
actionBars.setGlobalActionHandler("cut", cutAction);//"cut"为id,与某Retarget定义的id应该一致cutAction是要绑定的Action.
正因为在这里set,在RetargetAction的partActivated方法中才有如下代码:
public void partActivated(IWorkbenchPart part) {
super.partActivated(part);
IWorkbenchPartSite site = part.getSite();
//获取ActionBar
SubActionBars bars = (SubActionBars) ((PartSite) site).getActionBars();
bars.addPropertyChangeListener(propertyChangeListener);
//根据key从bars中取得相应的Action赋值给handler
setActionHandler(bars.getGlobalActionHandler(getId()));
}