Eclipse RCP 菜单和操作:配置还是编码?

发布于 2024-10-12 12:13:08 字数 401 浏览 2 评论 0原文

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

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

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

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

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

外界有什么意见?该应用程序将变得相当大,因此我想从一开始就采取正确的方法。也许有人可以给我指出一个配置嵌套菜单的示例:-)

This is a general question but my current problem revolves around menu handling.

In a normal plugin with contributes menu actions you would configure ActionSets etc in the plugin.xml configuration. This is obviously sensible.

I am working on a RCP application (actually RAP) and I'm wondering if it's worth the effort to configure everything via plugin.xml. My plugin does not have to interact with an other unknown plugins so, theoretically, I have control. I can add menus and actions programmatically.

I have been trying to configure a menu which contains a submenu. I have tried defining ActionSets and linking one inside the other but without success. Some items need to be disabled depending on the user role.

I figure I could have coded the whole lot in a few minutes but I'm not sure if that fits with the eclipse 'ethos'.

What opinions are out there? The application will get fairly big so I'd like to get the approach right from the start. Perhaps someone can point me at an example for configuring a nested menu :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

撩起发的微风 2024-10-19 12:13:08

我的观点是,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);
    }

}

有关如何实现这些功能的更多详细信息,请参见以下位置:

My opinion is that the plugin.xml implementation is the way to go.

My main two reasons for using this method:

  • It's really easy to reconfigure and reorganize the menus and buttons without writing java code.
  • Very clear hierarchical visualization of the menu trees.

Here is a code snippet that implements menus and submenus. In this example, they are added to the main menu.

You can paste this into your 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>

For activating/deactivating a menu, you have to use Core Expressions to enable/disable command handlers. If a command doesn't have any active handlers attached, it will be disabled. So, the menu item that calls that command will also be disabled.

The following code snippets show how to create a button on the toolbar of a view and have it be enabled/disabled depending of a variable's value. Bare in mind that you will have to change some things in this code to make it work. Most of the changes are for reference names and class implementation.

Create the button in the toolbar (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>

Create the command (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> 

Create the command handler (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> 

Create the state variable for the command (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>

Implement the class that changes the variable's state:

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);
    }

}

More details on how to implement these features can be found at these locations:

2024-10-19 12:13:08

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

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

  • UI 和处理始终是紧密相连的。没有办法将彼此分开

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

  • 在多个地方指定操作是维护的噩梦。如果您必须更改某个操作的图标,则需要更改所有位置。

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

    (1) 操作与命令

For Eclipse there are two different ways to contributing to the Workbench: Actions and Commands.

I definitely recommend the Commands as the newer and more advanced than Actions.
The drawbacks of Actions as specified here (1):

  • The UI and handling are always tied. There is no way you can separate each other

  • While Actions can be contributed to different parts of the workbench (popup menu/tool bar), all of them were different extension points and so you end up duplicating the XML in multiple places. The worst of it is that not all the extension points expect the same configuration.

  • Specifying Actions in multiple places is a maintenance nightmare. If you have to change the icon of an action, you need to change in all the places.

  • Another issue with duplicating Actions in plugin.xml is that multiple instance of the same Actions will be created in the memory

    (1) Actions vs Commands

初懵 2024-10-19 12:13:08

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

If you are writing the RCP application, the good practice is to create the place holders in your ActionBarAdvisor. While that would define the basic structure of your menus and toolbars, you can extend menuContributions and using commands to contribute the actual menu/tool items.

清风夜微凉 2024-10-19 12:13:08

要在 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);

For adding actions in RCP you can also use ApplicationActinBarAcvisor.It is more easy than the above mentioned solution
In this u just have to first declare the action as an object of IWorkbenchAction, then in method "protected void makeActions(IWorkbenchWindow window)" u can register it.
And the last step is to add it into menu.
Following code will help u out.

1.First declare the action :-

private IWorkbenchAction newAction

2.Registering action :-

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

3.Last step is to add the action in menu:-

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

You can also add the action in toolbar as follows:-

protected void fillCoolBar(ICoolBarManager coolBar) {
    IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
    coolBar.add(toolbar);
    toolbar.add(newAction);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文