我目前正在努力使用以下 Eclipse RCP 命令:
org.eclipse.ui.edit.cut
org.eclipse.ui.edit.copy
org.eclipse.ui.edit.paste
我将它们用作工具栏中的命令贡献,但当这些命令的“handled
”状态更改时,UIElement(工具栏项)不会更新。
为了测试,我使用轮询机制来验证这些命令的状态是否真的根据当前聚焦的元素而改变,我发现处理程序保持不变但处理程序的“已处理”状态正确改变,导致命令“已处理”状态也可以正确更改。
唯一的问题是,这些状态更改中的任何一个都不会导致通知(无论是在命令的 ICommandListener
上,还是在处理程序的 IHandlerListener
上>),因此 UIElement 不会更新。
下面是一些用于观察命令状态的测试代码:
ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
final String commandId="org.eclipse.ui.edit.copy";
Command command = commandService.getCommand(commandId);
command.addCommandListener(new ICommandListener() {
public void commandChanged (CommandEvent commandEvent) {
System.out.println(">> Command changed: " + commandId);
}
});
我是不是遗漏了什么,或者这是剪切/复制/粘贴处理程序实现中的错误? 有什么见解吗?
编辑:
命令一直处于启用状态,处理程序永远不会被交换,只有处理程序的“handled
”状态(因此也是 commmand 的“handled
”状态)根据哪个 ui 元素具有焦点而变化。但是,当此状态更改时没有通知。
这导致工具栏按钮始终处于启用状态,按下它们将导致 org.eclipse.core.commands.NotHandledException: There is no handler to execute for command
。
最佳答案
为剪切/复制/粘贴命令注册的处理程序是 org.eclipse.ui.internal.handlers.WidgetMethodHandler
。此处理程序检查是否在当前显示的焦点控件上声明了给定方法。执行时,该处理程序将使用反射调用该方法。
来自 WidgetMethodHandler 的片段:
public final boolean isHandled() {
return getMethodToExecute() != null;
}
getMethodToExecute()
将使用 Display.getCurrent().getFocusControl()
定位当前焦点控件,然后检查是否在其上声明了给定的触发方法.
org.eclipse.swt.widgets.Text
等小部件有cut()
、copy()
和paste( )
方法,因此当焦点位于此类小部件上时,处理程序将为 isHandled()
返回“true”。
然而,当当前焦点控件发生变化时,此处理程序并不知道(我认为甚至没有一种方法可以在显示器上观察到这一点),因此无法通知其动态“isHandled”状态的变化。
这导致剪切/复制/粘贴命令适用于弹出菜单,但它们在工具栏中使用时问题很大,因为当处理程序没有通知时,它们的 UI 元素无法正确更新。
这让我要么不使用工具栏中的这些命令,要么使用轮询机制来更新 ui 元素(这也很糟糕且容易出错)。 :-(
关于 eclipse RCP : how to observe the states of the cut/copy/paste commands?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/909895/