12

这是一个普遍的问题,但我目前的问题围绕着菜单处理。

在具有贡献菜单操作的普通插件中,您可以在 plugin.xml 配置中配置 ActionSets 等。这显然是明智的。

我正在开发一个 RCP 应用程序(实际上是 RAP),我想知道是否值得通过 plugin.xml 配置所有内容。我的插件不必与其他未知插件交互,所以理论上我可以控制。我可以以编程方式添加菜单和操作。

我一直在尝试配置一个包含子菜单的菜单。我曾尝试定义 ActionSet 并将其中一个链接到另一个,但没有成功。根据用户角色,需要禁用某些项目。

我想我可以在几分钟内编写全部代码,但我不确定这是否符合 eclipse 的“精神”。

外面有什么意见?该应用程序将变得相当大,所以我想从一开始就采用这种方法。也许有人可以指点我一个配置嵌套菜单的例子:-)

4

4 回答 4

25

我的观点是 plugin.xml 实现是要走的路。

我使用这种方法的两个主要原因:

  • 无需编写 java 代码即可重新配置和重新组织菜单和按钮。
  • 菜单树的层次结构非常清晰。

这是一个实现菜单和子菜单的代码片段。在本例中,它们被添加到主菜单中。

您可以将其粘贴到您的 plugin.xml 中:

<extension
         name="Main Menu Contributions"
         point="org.eclipse.ui.menus">
 <menuContribution
        allPopups="false"
        locationURI="menu:org.eclipse.ui.main.menu">
     <menu
           id="fileMenu"
           label="File">
        <command
              commandId="org.eclipse.ui.file.exit"
              label="Exit"
              style="push">
        </command>
     </menu>
     <menu
           label="Edit">
        <command
              commandId="org.eclipse.ui.edit.selectAll"
              label="Select All"
              style="push">
        </command>
        <menu
              label="Submenu">
           <command
                 commandId="org.eclipse.ui.edit.selectAll"
                 label="Select All Submenu"
                 style="push">
           </command>
           <command
                 commandId="org.eclipse.ui.edit.delete"
                 label="Delete submenu"
                 style="push">
           </command>
        </menu>
     </menu>
  </menuContribution>
</extension>

要激活/停用菜单,您必须使用核心表达式来启用/禁用命令处理程序。如果命令没有附加任何活动的处理程序,它将被禁用。因此,调用该命令的菜单项也将被禁用。

以下代码片段显示了如何在视图的工具栏上创建一个按钮,并根据变量的值启用/禁用它。请记住,您必须更改此代码中的某些内容才能使其正常工作。大多数更改是针对引用名称和类实现的。

在工具栏中创建按钮(plugin.xml):

   <extension
         name="View Toolbar Contributions"
         point="org.eclipse.ui.menus">
      <menuContribution
            allPopups="false"
            locationURI="toolbar:myapp.views.MyView">
       <command
             commandId="myapp.commands.PauseSound"
             icon=""
             label="Pause Playback Sound"
             style="push"
             tooltip="Pause">
       </command>
     </menuContribution>
</extension>

创建命令(plugin.xml):

<extension
         id="myapp.commands.PauseSound"
         name="Pause sound command"
         point="org.eclipse.ui.commands">
      <command
            id="myapp.commands.PauseSound"
            name="Pause Sound">
      </command>
</extension> 

创建命令处理程序(plugin.xml):

<extension
         point="org.eclipse.ui.handlers">
      <handler
            commandId="myapp.commands.PauseSound">
         <activeWhen>
            <with
                  variable="myapp.commands.sourceprovider.active">
               <or>
                  <equals
                        value="PLAYING">
                  </equals>
                  <equals
                        value="PAUSED">
                  </equals>
               </or>
            </with>
         </activeWhen>
         <class
               class="myapp.rcp.commands.toolbar.PausePlayback">
         </class>
      </handler>
</extension> 

为命令 (plugin.xml) 创建状态变量:

   <extension
         point="org.eclipse.ui.services">
      <sourceProvider
            provider="myapp.commands.sourceprovider.CommandState">
         <variable
               name="myapp.commands.sourceprovider.active"
               priorityLevel="workbench">
         </variable>
      </sourceProvider>
   </extension>

实现改变变量状态的类:

public class CommandState extends AbstractSourceProvider {
    public final static String STATE = "myapp.commands.sourceprovider.active";
    public final static String STOPPED = "STOPPED";
    public final static String PLAYING = "PLAYING";
    public final static String PAUSED = "PAUSED";
    public final static String NOT_LOADED = "NOT_LOADED";

enum State {
        NOT_LOADED, PLAYING, PAUSED, STOPPED
    };
    private State curState = State.NOT_LOADED;

    @Override
    public void dispose() {
    }

    @Override
    public String[] getProvidedSourceNames() {
        return new String[] { STATE };
    }

    // You cannot return NULL
    @SuppressWarnings("unchecked")
    @Override
    public Map getCurrentState() {
        Map map = new HashMap(1);
        if (curState == State.PLAYING)
            map.put(STATE, PLAYING);
        else if (curState == State.STOPPED)
            map.put(STATE, STOPPED);
        else if (curState == State.PAUSED)
            map.put(STATE, PAUSED);

        return map;
    }

    public void setPlaying() {
        fireSourceChanged(ISources.WORKBENCH, STATE, PLAYING);
    }

    public void setPaused() {
        fireSourceChanged(ISources.WORKBENCH, STATE, PAUSED);
    }

    public void setStopped() {
        fireSourceChanged(ISources.WORKBENCH, STATE, STOPPED);
    }

    public void setNotLoaded() {
        fireSourceChanged(ISources.WORKBENCH, STATE, NOT_LOADED);
    }

}

可以在以下位置找到有关如何实现这些功能的更多详细信息:

于 2011-05-25T12:15:08.553 回答
1

对于 Eclipse,有两种不同的方式为 Workbench 做出贡献:Actions 和 Commands。

我绝对推荐命令作为比操作更新和更高级的。此处指定的操作的缺点 (1):

  • UI 和处理总是联系在一起的。没有办法彼此分开

  • 虽然动作可以贡献给工作台的不同部分(弹出菜单/工具栏),但它们都是不同的扩展点,因此您最终会在多个位置复制 XML。最糟糕的是,并非所有扩展点都期望相同的配置。

  • 在多个地方指定操作是一场维护噩梦。如果你必须改变一个动作的图标,你需要改变所有的地方。

  • 在 plugin.xml 中复制 Actions 的另一个问题是,将在内存中创建相同 Actions 的多个实例

    (1)动作与命令

于 2012-10-17T08:42:44.430 回答
0

如果您正在编写 RCP 应用程序,好的做法是在 ActionBarAdvisor 中创建占位符。虽然这将定义菜单和工具栏的基本结构,但您可以扩展 menuContributions 并使用命令来贡献实际的菜单/工具项。

于 2011-03-18T10:20:39.400 回答
0

要在 RCP 中添加动作,您还可以使用 ApplicationActinBarAcvisor。它比上述解决方案更容易在此您只需首先将动作声明为 IWorkbenchAction 的对象,然后在方法“protected void makeActions(IWorkbenchWindow window)”中即可注册它。最后一步是将其添加到菜单中。以下代码将帮助您。

1.首先声明动作:-

private IWorkbenchAction newAction

2.注册动作:-

protected void makeActions(IWorkbenchWindow window) {
newAction = ActionFactory.NEW_WIZARD_DROP_DOWN.create(window);
    register(newAction);
    newAction.setText("New");

3.最后一步是在菜单中添加操作:-

MenuManager filemenu = new MenuManager("&File", "file");
    filemenu.add(newAction);

您还可以在工具栏中添加操作,如下所示:-

protected void fillCoolBar(ICoolBarManager coolBar) {
    IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
    coolBar.add(toolbar);
    toolbar.add(newAction);
于 2013-05-03T09:20:53.077 回答