2011-01-19 61 views
12

这是一个普遍的问题,但我目前的问题围绕菜单处理。Eclipse RCP菜单和操作:配置或编码?

在一个普通的插件中,你可以在plugin.xml配置中配置ActionSets等。这显然是明智的。

我正在研究RCP应用程序(实际上是RAP),我想知道是否值得通过plugin.xml来配置所有内容。我的插件不需要与其他未知的插件进行交互,因此理论上我有控制权。我可以通过编程添加菜单和动作。

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

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

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

回答

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> 

创建命令处理程序(插件。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); 
    } 

} 

更多细节要实现这些功能可以在以下位置找到:

+4

+1好例子! – 2011-08-20 14:46:55

0

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

1

对于Eclipse有两种不同的方式来促进工作台:动作和命令。

我绝对推荐Commands作为比Actions更新,更先进的命令。 这里指定的动作的缺点(1):

  • UI和处理总是捆绑在一起。没有办法让你互相分离
  • 尽管Actions可以被分配到工作台的不同部分(弹出式菜单/工具栏),但它们都是不同的扩展点,所以你最终会在多个地方复制XML。最糟糕的是,并非所有的扩展点都需要相同的配置。
  • 在多个地方指定操作是一个维护噩梦。如果您必须更改某个动作的图标,则需要在所有地方进行更改。
  • 在plugin.xml中重复操作的另一个问题是,同样的动作的多个实例将在存储

    (1)Actions vs Commands

0

创建对于RCP你也可以添加动作使用ApplicationActinBarAcvisor.It比上面提到的解决方案更容易 在这里你只需要首先声明动作作为IWorkbenchAction的一个对象,然后在方法“保护无效makeActions(IWorkbenchWindow窗口)”你可以注册它。 最后一步是将其添加到菜单中。 以下代码将帮助你。

1.首先声明的操作: -

private IWorkbenchAction newAction 

2.注册行动: -

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

3.Last一步是添加操作菜单: -

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