如何在Eclipse 4.x RCP应用中以编程方式调用撤销功能?
在Eclipse 4.x中通过代码调用撤销(Undo)功能的正确方式
你遇到的问题核心在于Eclipse 3.x到4.x的命令处理机制变更——像org.eclipse.ui.edit.undo这类和活动编辑器强关联的命令,其Handler的查找逻辑变得更依赖上下文信息,而你原有的代码用空的ExecutionEvent调用executeWithChecks,无法提供命令所需的当前活动编辑器、窗口等上下文,导致找不到可用的Handler。
为什么工具栏的撤销按钮能正常工作?
工具栏按钮的点击事件是在Eclipse的UI上下文环境中触发的,系统会自动把当前活动编辑器、窗口等上下文信息注入到命令执行流程中,所以能找到对应的Handler。而你手动创建的空ExecutionEvent没有携带这些关键信息,自然会抛出NotHandledException。
解决方案:使用IHandlerService执行命令
在Eclipse 4.x中,推荐通过IHandlerService来执行这类上下文相关的命令,它会自动处理当前的UI上下文,确保命令找到正确的Handler。替换你原有代码为以下实现:
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotDefinedException; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; // 获取服务定位器 IServiceLocator serviceLocator = PlatformUI.getWorkbench(); // 获取IHandlerService实例 IHandlerService handlerService = serviceLocator.getService(IHandlerService.class); try { // 执行撤销命令,第二个参数传null即可,HandlerService会自动注入当前上下文 handlerService.executeCommand("org.eclipse.ui.edit.undo", null); } catch (ExecutionException | NotDefinedException | NotEnabledException | NotHandledException e) { logger.error("Error executing undo command", e); }
可选方案:构造带上下文的ExecutionEvent
如果你坚持要使用Command.executeWithChecks,需要手动构造包含当前UI上下文的ExecutionEvent,代码如下:
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ICommandService; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotDefinedException; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.commands.operations.IEvaluationContext; import java.util.Collections; IServiceLocator serviceLocator = PlatformUI.getWorkbench(); ICommandService commandService = serviceLocator.getService(ICommandService.class); IHandlerService handlerService = serviceLocator.getService(IHandlerService.class); Command undoCommand = commandService.getCommand("org.eclipse.ui.edit.undo"); // 获取当前的UI上下文 IEvaluationContext currentContext = handlerService.getCurrentState(); // 构造包含上下文的ExecutionEvent ExecutionEvent event = new ExecutionEvent(undoCommand, Collections.emptyMap(), null, currentContext); try { undoCommand.executeWithChecks(event); } catch (NotDefinedException | NotEnabledException | NotHandledException | ExecutionException e) { logger.error("Error executing undo command", e); }
关键说明
IHandlerService是Eclipse 4.x中处理命令执行的推荐方式,它会自动管理当前活动窗口、编辑器等上下文信息,避免手动构造ExecutionEvent的繁琐和错误。- 确保调用代码时,当前确实有活动编辑器且处于激活状态(你已经确认这一点,所以没问题)。
内容的提问来源于stack exchange,提问作者user-27
相关产品推荐
相关产品推荐

