如何确保Eclipse操作栏菜单项稳定显示?
问题分析与解决方案
你遇到的问题是在Eclipse操作栏添加菜单项时,第二个项偶尔不显示,修改无关代码还会影响该行为。核心原因是直接在ContributionItem的fill方法中手动创建SWT MenuItem,未遵循Eclipse ActionBar的生命周期管理机制,导致UI更新不彻底或索引冲突。
以下是具体解决思路和修改方案:
1. 替换手动创建MenuItem的方式,使用Eclipse标准IAction
Eclipse的MenuManager更适合管理基于IAction的菜单项,而非直接操作SWT控件,能确保UI更新被正确触发:
public void setModelViewMenu(ModelView modelView) { this.modelView = modelView; if (this.modelView != null) { IActionBars actionBars = modelView.getViewSite().getActionBars(); IMenuManager dropDownMenu = actionBars.getMenuManager(); dropDownMenu.removeAll(); if (modelView.getModelViewContent() != null) { OntoDescriptor viewDesc = modelView.getModelViewContent().getViewpointDescriptor(); IAction alertAction = new Action("Show alerts") { @Override public void run() { // 原ListAlerts监听器的逻辑 } }; alertAction.setToolTipText("List alerts for " + modelView.getPartName() + " in a popup"); dropDownMenu.add(alertAction); IAction saveAsAction = new Action("Save viewpoint as...") { @Override public void run() { // 原SaveAsViewpoint监听器的逻辑 } }; saveAsAction.setToolTipText("Save viewpoint in a workspace file"); dropDownMenu.add(saveAsAction); } actionBars.updateActionBars(); } }
2. 若必须使用自定义ContributionItem,修复fill方法问题
如果需要保留AllowedContributionItem的逻辑,需确保手动创建MenuItem后强制更新菜单布局,且避免索引冲突:
protected class FillModelViewPulldown extends AllowedContributionItem { @Override public void fill(Menu menu, int index) { if (modelView.getModelViewContent() != null) { OntoDescriptor viewDesc = modelView.getModelViewContent().getViewpointDescriptor(); // 不指定固定索引,让SWT自动处理位置 MenuItem alertItem = new MenuItem(menu, SWT.DROP_DOWN); alertItem.setText("Show alerts"); alertItem.setToolTipText("List alerts for " + modelView.getPartName() + " in a popup"); alertItem.addSelectionListener(new ListAlerts()); MenuItem menuItem = new MenuItem(menu, SWT.DROP_DOWN); menuItem.setText("Save viewpoint as..."); menuItem.setToolTipText("Save viewpoint in a workspace file"); menuItem.addSelectionListener(new SaveAsViewpoint(modelView, viewDesc)); // 强制更新菜单布局,确保新添加的项被渲染 menu.layout(true); } } }
3. 检查AllowedContributionItem父类的限制
确认AllowedContributionItem的isVisible()或isEnabled()方法是否存在动态判断逻辑,可能导致第二个菜单项被意外隐藏。如果父类有过滤规则,需确保两个菜单项都符合显示条件。
4. 确保ActionBars更新时机正确
所有UI操作必须在SWT UI线程执行,如果setModelViewMenu可能被非UI线程调用,需用Display.getDefault().asyncExec()包裹更新逻辑:
Display.getDefault().asyncExec(() -> { actionBars.updateActionBars(); });
内容的提问来源于stack exchange,提问作者Steve Vestal
相关产品推荐
相关产品推荐

