e4动态菜单贡献

时间:2012-09-07 09:50:28

标签: eclipse e4

此功能已在Kepler M4中实现,有关用法的详细信息,请参阅my blog

我想实现对位于视图工具栏中的处理程序菜单的完全动态菜单贡献。在Eclipse 3中,可以将“dynamic”作为org.eclipse.ui.menus贡献添加到菜单中!

我已经发现www.vogella.com/blog/2010/10/26/processors-e4-model解释了如何通过处理器模型扩展动态地为菜单做出贡献,但我说的是一个完全动态的菜单实现,它在每次调用resp时都会发生变化。子菜单。如前所述,通过动态菜单贡献和isDynamic()设置为true,在Eclipse 3.x中实现这一点没有问题。

我已经尝试了几种方法:

  • 注册连接到菜单的处理器=>没有动态添加(新元素根本不显示,也在Eclipse Forum - Cannot replace menu items at runtime中讨论)
  • 在创建菜单的过程中收听UIEventTopic,获取Modification的小部件=>收集的swt.Menu的修改被忽略(每个听众,元素等)(对于信息RCP Event Model

开放,未经验证的解决方案

  • 插入ToolControl以尝试SWT方法 - >很复杂但可能有用

我现在已经敲了一段时间,但似乎无法理解E4中这个问题的正确实现。

- 此问题也在Eclipse Forum - Dynamic menu contributions

中提出

-----更新

到目前为止我尝试了一种不同的方法:

我在菜单中添加了HandledToolItem(请参见下图)

Fragment command approach

并且使用以下代码我试图干扰菜单构建方式,其中代码由resp调用。命令处理程序在图像中引用。

@CanExecute
    public boolean canExecute(@Optional MApplication application) {
        System.out.println("CanExecute Counter="+counter);
            // --- 1 ---
        // Find the required MMenu Entry in the Application Model
        if(application == null) return true;
        EModelService modelService = (EModelService) application.getContext().get(EModelService.class.getName());
        MPart part = (MPart) modelService.find("at.medevit.emr.contacts.ui.contactselector", application);
        List<MToolBarElement> lmte = part.getToolbar().getChildren();
        HandledToolItemImpl htil = null;
        for (MToolBarElement mToolBarElement : lmte) {
            if(mToolBarElement.getElementId().equals("at.medevit.emr.contacts.ui.contactselector.toolbar.handledtoolitem.filter")) htil = (HandledToolItemImpl) mToolBarElement;
        }
        if(htil != null) {
            MMenu elemMenu = htil.getMenu();
        // --- 2 ---
            // Found it hopefully, let's start the real work, simply add a new item
        MDirectMenuItem mdi = MMenuFactory.INSTANCE.createDirectMenuItem();
        mdi.setLabel("Counter "+counter);
        counter++;
            // --- 3 ---
        elemMenu.getChildren().add(mdi); // ConcurrentModificationException
        }

可以看出,创建菜单后会查询此代码,以确定该命令是否可执行。 1 - 2的所有代码都是找到正确的MMenu元素。 2 - 3中的代码创建一个MenuItem并在字段中递增计数器。

但是在第3次我第一次打开菜单时会遇到 java.util.ConcurrentModificationException !我假设在这一点上菜单迭代了elemMenu.getChildren()并且我不允许启用!

所以关于整个e4模型的所有模糊都是可以随时更改的;)(就像孩子'我知道这是一个笨蛋!)

事情是:我真的认为添加完全动态菜单部件的可能性是最好的可用性工具之一,如果不能像E3那样在E4中实现它,这是一个非常严重的可能性降级!!!

- 更新

已为此https://bugs.eclipse.org/bugs/show_bug.cgi?id=389063

提交了Eclipse Bug

1 个答案:

答案 0 :(得分:2)

应该在您打开的错误中处理正确的动态模型更新。作为Juno中Eclipse4的变通方法,可以在Eclipse4中创建MRenderedMenuItem,以提供与动态元素相同的功能(尽管如果使用4.2,则只需使用org.eclipse.ui.menus )。

例如:

ContextFunction generator = new ContextFunction() {
    @Override
    public Object compute(IEclipseContext context) {
        return new MyCompoundContributionItem(context);
    }
};

MRenderedMenuItem menuItem = MenuFactoryImpl.eINSTANCE.createRenderedMenuItem();
menuItem.setElementId(id);
menuItem.setContributionItem(generator);
container.getChildren().add(menuItem);

这有效地将CompoundContributionItem提供给Eclipse4菜单渲染器。