2011-01-19 58 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);