内嵌Editor中Action的问题

Editor中嵌入Editor,最大的问题就是Action的问题。

我们知道,通过每个Editor都有自己对应的Action组,我们通过提供Editor的Contributor来提供该Editor对应的Actions。但是这在内嵌Editor中就会有问题了。例如,我有一个GEF的Editor:ZillionaireEditor。这个Editor嵌套在另一个Editor中:ZillionaireComboEditor。

 

假如在我的ZillionaireComboEditor中,需要支持ZillionaireEditor的redo、undo和delete动作。

 

那么首先,我们在我们的ZillionaireComboEditor对应的Contributor里追加用于支持GEF command的这三个动作:

	@Override
	protected void buildActions() {
		addRetargetAction(new UndoRetargetAction());
		addRetargetAction(new RedoRetargetAction());
		addRetargetAction(new DeleteRetargetAction());
	}

	@Override
	public void contributeToToolBar(IToolBarManager toolBarManager) {
		toolBarManager.add(getAction(ActionFactory.UNDO.getId()));
		toolBarManager.add(getAction(ActionFactory.REDO.getId()));
		toolBarManager.add(getAction(ActionFactory.DELETE.getId()));
	}

 这个很简单,不过只是这样,也会有问题,看看error view就知道,会在ActionBarContributor.setActiveEditor(ActionBarContributor.java:142)有一个空指针的异常。

 

简单的修正方法如下:

	@Override
	public void setActiveEditor(IEditorPart editor) {
		if (editor instanceof ZillionaireComboEditor) {
			super.setActiveEditor(((ZillionaireComboEditor) editor)
					.getZillionaireEditor());
		} else {
			super.setActiveEditor(editor);
		}
	}

 

重写它的setActiveEditor()方法,代理到ZillionaireEditor上去。

 

这时redo和undo的支持就实现了。不过delete操作会有问题:没反应。

 

实际中,我们选择任一editPart,delete操作都应该被更新,以判断是否可以招待该操作。

所以显示,会有一个选择监听来做这件事。看看GraphicalEditor里的selectionChange()方法:

/**
 * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
 */
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
	// If not the active editor, ignore selection changed.
	if (this.equals(getSite().getPage().getActiveEditor()))
		updateActions(selectionActions);
}

 

因为我们用外层的editor包装了内部的editor,所以此时判断条件:this.equals(getSite().getPage().getActiveEditor()返回值为false,因此updateActions()方法无法被调用。

 

显然,我们不应该想着通过修改ZillionaireEditor来实现,因为通常被包装的Editor都不能被你所修改。

 

所以看来,我们只有通过其他的方法来修改了。

例如,我们在ZillionaireComboEditor中也增加一个selectionListener:

getSite().getPage().addSelectionListener(this);

 

然后实现selectionChange()方法:

	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		if (this.equals(getSite().getPage().getActiveEditor())) {
			ZillionaireEditorContributor actionBarContributor = (ZillionaireEditorContributor) getEditorSite()
					.getActionBarContributor();
			DeleteRetargetAction action = (DeleteRetargetAction) actionBarContributor
					.getAction(ActionFactory.DELETE.getId());
			if (action.getActionHandler() instanceof UpdateAction)
				((UpdateAction) action.getActionHandler()).update();
		}
	}

 然后delete操作就可用了。

 

后记:

这只是我自己的一个理解,不知是否有其他好的方法去解决这个问题!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值