Top / Eclipse / プラグイン開発のTIPS集 / org.eclipse.ui.IViewActionDelegate(ポップアップ・メニューバー)

すでに他のプラグイン開発者から提供されているビュー(IViewPart?の実装クラスね)内に配置されているウィジェットのポップアップメニューにアクションを追加したり、そのビュー自体のメニューバーにアクションを追加したいときには、このクラスを使用します。

  • ビュー自体のメニューバーにアクションを追加
    pic2.png


  • ビュー内のウィジェット(例はTableViewer?)のポップアップメニューにアクションを追加
    pic1.png

ビュー自体のメニューバーにアクションを追加する。

拡張ポイント

org.eclipse.ui.viewActions

plugin.xmlのサンプル

<extension point="org.eclipse.ui.viewActions">
 <viewContribution
   id="nu.mine.kino.plugin.samples.rcp.viewContribution2"
   targetID="nu.mine.kino.plugin.samples.rcp.view3">
  <action
      class="nu.mine.kino.plugin.samples.rcp.ViewActionDelegate2"
      id="nu.mine.kino.plugin.samples.rcp.action2"
      label="アクション3" menubarPath="addition"
      style="push"/>
 </viewContribution>
</extension>


引き続き、ビュー内のViewerクラスのポップアップメニューにアクションを追加する方法です。

ビュー内のViewerクラスのポップアップメニューにアクションを追加する。

拡張ポイント

org.eclipse.ui.popupMenus

その前に

他のビュー内のViewerのポップアップメニューにアクションを追加するにはビュー側で「そのViewerが使っているポップアップメニューを公開してくれている」ことが前提となっています。具体的には

 getSite().registerContextMenu(menuMgr, getSite().getSelectionProvider());

を使ってビューがメニューを公開してくれている必要があります。

さて、通常ビューを作るときは以下のようなサンプルになると思います。

public void createPartControl(Composite parent) {
  viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
      | SWT.V_SCROLL);
  ...
  makeActions(); <- フィールドのアクションをnewする
  hookContextMenu();
  hookDoubleClickAction();
  contributeToActionBars();
}
private void hookContextMenu() {
  ↓そのビュー用のMenuManagerを作る
  MenuManager menuMgr = new MenuManager("#PopupMenu");
  menuMgr.setRemoveAllWhenShown(true);
  menuMgr.addMenuListener(new IMenuListener() {
    public void menuAboutToShow(IMenuManager manager) {
      fillContextMenu(manager);
    }
  });

  ↓MenuManagerを使って(ビュー内の)viewerにコンテキストメニューを作る
  Menu menu = menuMgr.createContextMenu(viewer.getControl());
  viewer.getControl().setMenu(menu);
  
  ↓そのビューのメニューマネージャを外部に公開する
  getSite().registerContextMenu(menuMgr, viewer);
}
private void fillContextMenu(IMenuManager manager) {
  manager.add(action1);
  manager.add(action2);
  // Other plug-ins can contribute there actions here
  manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
  ↑ メニューの追加させたい場所にキー値(IWorkbenchActionConstants.MB_ADDITIONS)
     (実際の文字列はadditions)をセットしておく。
}

ビュー側がこんな風になっていれば、外部からビュー内のViewerにアクションを追加することができます。

ところで

getSite().registerContextMenu(menuMgr, viewer);

の第二引数の型はISelectionProvider?なのですが、まだ役目がよくわかってません。とりあずviewerや getSite().getSelectionProvider?()ってなってるのが多いです。たぶん、アクションを実装するときに、どのオブジェクトが選択されているかがわからないと困りますが、その時に使用すんのかな??。複数のViewerがあったときになんか使うとか??

2006/3/30追記
わかりました。Eclipse/プラグイン開発のTIPS集/getSite().registerContextMenuを理解するにまとめましたが、拡張ポイントを使ってそのポップアップメニューにアクションを追加したとき、そのアクションに使用させるSelectionProvider?を渡すみたいです。この例ではmenuMgrというメニューが外部に公開されていますが、そこにアクションを追加したとき、そのIViewActionDelegate?の実装クラスに渡されるISelectionクラスを提供するのがviewerですよ、と指定しています。

ちなみにプロパティシートを使う で書きましたが、プロパティシートに、ビュー内のどのオブジェクトが選択されているかを通知するときにはSelectionProvider?を使用しましたね。

plugin.xml のサンプル

getSite().registerContextMenu(menuMgr, viewer);
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

としたことで、

  • 外部にポップアップはmenuMgrを公開しますよ
  • そのポップアップのIDはビューのIDですよ
  • ポップアップにアクションを追加するときにplugin.xmlに指定するキー値(targetID)はビューのIDですよ*1
  • plugin.xmlのmenubarPathはIWorkbenchActionConstants?.MB_ADDITIONSという文字列*2ですよ
  • 追加したアクションクラスに選択したものを通知するSelectionProvider?はviewerですよ

という事になります。ここまでビュー側で設定してくれていると、そのビュー内のメニューに対して別のプラグインがアクションを追加することができます。

アクションを追加するにはplugin.xmlで以下のように

  • targetID: アクションを追加したいメニューのID
  • menubarPath: そのメニューの追加する場所

を宣言すればOKです。

<extension point="org.eclipse.ui.popupMenus">
  <viewerContribution
     id="nu.mine.kino.plugin.samples.rcp.viewerContribution1"
     targetID="nu.mine.kino.plugin.samples.rcp.view3">
                ↑ これはビューのIDではなく registerContextMenu でセットしたID
                   でもデフォルト値がビューのIDなのでほとんどビューのIDと同じか
    <action
      class="nu.mine.kino.plugin.samples.rcp.Action4"
      ↑ IViewActionDelegateの実装クラス
      id="nu.mine.kino.plugin.samples.rcp.action4"
      label="アクション4"
      menubarPath="additions"/>
      ↑ additionsは IWorkbenchActionConstants.MB_ADDITIONSの文字列
  </viewerContribution>
</extension>

実装クラスのサンプルソース

追加されたアクションがメニューで選択された場合に起動されるクラスは以下の通り。

package nu.mine.kino.plugin.samples.rcp;

import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;

public class Action4 implements IViewActionDelegate {
  private ISelection selection;
  private IViewPart view;
  public void init(IViewPart view) {
    this.view = view;
  }
  public void run(IAction action) {

    if (selection instanceof IStructuredSelection) {
      IStructuredSelection sselection = (IStructuredSelection) selection;
      String firstElement = (String) sselection.getFirstElement();
      System.out.println(firstElement);
    }
  }

 public void selectionChanged(IAction action, ISelection selection) {
    this.selection = selection;
  }
}

いやあ長かった。これでようやく外部のプラグインがビューのポップアップにアクションを追加できました。別のプラグインに追加するためには、そのビューが指定するtargetIDが必要ですね。

関連リンク


この記事は

選択肢 投票
おもしろかった 3  
そうでもない 0  
  • registerContextMenu?の第二引数ってなんのために必要なんだろうなー -- きの? 2006-03-12 22:40:32 (日)
  • ビューのメニューバーに追加するときはビューのIDを、ポップアップメニューに追加するときはそのメニューのID*3をtargetIDに指定すればよいんですね。ただポップアップメニューのばあいはビュー提供側がメニューを公開しててくれないとダメ、ですね。あれメニューバーに追加させたくない場合はどうするんだっけ?? -- きの? 2006-03-13 00:58:34 (月)
  • SelectionProvider?とregisterContextMenu?をいっつも混同しちゃう。SelectionProvider?は選択オブジェクトを外部に通知するモノを指定する、registerContextMenu?は外部に公開するViewerを指定する、か。だいたい、この辺はviewの設定に書きたいぞ。。 -- きの? 2006-08-03 17:14:26 (木)

Top / Eclipse / プラグイン開発のTIPS集 / org.eclipse.ui.IViewActionDelegate(ポップアップ・メニューバー)

現在のアクセス:12970


*1 もしくはgetSite().registerContextMenu?("hogeID",menuMgr, viewer);とやってある場合は、hogeIDがキー値。
*2 "additions"という文字列
*3 てもほとんどビューのIDのはず

添付ファイル: filepic2.png 1263件 [詳細] filepic1.png 1259件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-02-10 (水) 15:12:07 (5179d)