如何在Software AG Web Designer的Package Navigator中编程调用节点刷新功能?
针对你的需求——在自研插件里编程触发Package Navigator节点的Refresh功能,结合你找到的RefreshFromServerAction类和扩展点配置,这里有两种靠谱的实现方式,我分别给你拆解清楚:
方案一:直接实例化并执行RefreshFromServerAction(最直接的方式)
既然你已经拿到了目标Action的源码,直接实例化它、注入选中节点、调用执行是最直观的做法。不过要注意这个Action依赖IStructuredSelection来确定要刷新的节点,步骤如下:
代码示例
// 1. 先获取你要刷新的目标节点(比如ISLazyTreeParent类型的实例) ISLazyTreeParent targetRefreshNode = ...; // 2. 将目标节点包装成Action需要的IStructuredSelection IStructuredSelection targetSelection = new StructuredSelection(targetRefreshNode); // 3. 实例化RefreshAction,设置选中项并执行 RefreshFromServerAction refreshAction = new RefreshFromServerAction(); refreshAction.selectionChanged(null, targetSelection); refreshAction.run();
注意事项
- 检查节点的启用条件:原扩展点里的
<enablement>规则要求节点满足vcsEnabled或vcsNotEnabled属性,你要确保目标节点符合这个条件,否则Action可能不会正常执行。 - 服务器连接状态:Action内部会检查节点对应的
ServerConnection是否处于连接状态,如果未连接会直接返回不执行,所以调用前要确保服务器已连接。 - 依赖兼容性:这种方式直接依赖第三方插件的具体类,如果对方后续更新插件修改了这个类的结构或方法,你的代码可能会报错,需要留意版本兼容性。
方案二:利用Eclipse标准命令框架调用(推荐,低耦合)
从你提供的扩展点配置可以看到,RefreshFromServerAction绑定了Eclipse标准的org.eclipse.ui.file.refresh命令(通过definitionId属性)。这种情况下,我们可以利用Eclipse的命令框架来触发刷新,不需要直接依赖第三方的Action类,更符合Eclipse插件的标准实践。
代码示例
try { // 1. 先激活Software AG导航器插件(确保它已加载) Bundle navigatorBundle = Platform.getBundle("com.softwareag.is.ui.navigator"); if (navigatorBundle != null && navigatorBundle.getState() != Bundle.ACTIVE) { navigatorBundle.start(Bundle.START_TRANSIENT); } // 2. 获取Package Navigator视图(需要确认视图的实际ID,可通过插件扩展点org.eclipse.ui.views查找) String navigatorViewId = "com.softwareag.is.ui.navigator.PackageNavigator"; IViewPart navigatorView = PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getActivePage().findView(navigatorViewId); if (navigatorView != null) { IWorkbenchPartSite site = navigatorView.getSite(); ISLazyTreeParent targetNode = ...; // 你的目标刷新节点 IStructuredSelection selection = new StructuredSelection(targetNode); // 3. 获取标准REFRESH命令 Command refreshCommand = CommandManager.getInstance() .getCommand(ActionFactory.REFRESH.getId()); // 4. 构建命令执行上下文,注入选中的节点 IEvaluationContext evalContext = new EclipseContextFactory() .createContext(site.getShell()); evalContext.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, selection); ExecutionEvent event = new ExecutionEvent(refreshCommand, Collections.emptyMap(), null, evalContext); // 5. 执行命令 refreshCommand.executeWithChecks(event); } } catch (Exception e) { // 处理各种异常:视图未找到、命令不可用、插件激活失败等 // 这里可以用你自研插件的日志工具记录错误 e.printStackTrace(); }
为什么推荐这种方式?
- 低耦合:不需要直接引用第三方插件的具体Action类,只要命令ID不变,即使对方更新插件内部实现,你的代码也能正常工作。
- 自动遵循启用规则:命令执行时会自动检查原扩展点的
<enablement>条件,不需要你手动判断节点是否符合要求。 - 符合Eclipse生态规范:使用标准命令框架是Eclipse插件开发的最佳实践之一,代码更健壮、可维护性更高。
总结
- 如果追求快速实现、且能接受依赖第三方插件的具体类,方案一足够简单直接;
- 如果希望代码更健壮、低耦合,优先选择方案二,这也是更推荐的方式。
内容的提问来源于stack exchange,提问作者Farhan stands with Palestine
相关产品推荐
相关产品推荐

