【问题标题】:Eclipse RCP menus & actions: Configure or code?Eclipse RCP 菜单和操作:配置还是编码?
【发布时间】:2011-06-11 20:35:05
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: eclipse-rcp eclipse-rap plugin.xml


    【解决方案1】:

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

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

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

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

    您可以将其粘贴到您的 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>
    

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

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

    在工具栏中创建按钮(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);
        }
    
    }
    

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

    【讨论】:

    • 我发现整个检查、更改、重新加载周期太慢了,尤其是当您有很多需要调试复杂行为的上下文菜单时。但我可以看到它在该示例中是如何工作的。
    【解决方案2】:

    对于 Eclipse,有两种不同的方式为工作台做出贡献:操作和命令。

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

    • UI 和处理总是相关联的。没有办法彼此分开

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

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

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

      (1)Actions vs Commands

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        对于在 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);
        

        【讨论】:

          猜你喜欢
          • 2011-07-17
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          • 1970-01-01
          • 2010-12-03
          • 2012-11-26
          • 2012-04-03
          • 1970-01-01
          相关资源
          最近更新 更多