// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
viewerをビューに配置していくときに、最後に必ずと言っていいほど記述する、
 getSite().registerContextMenu(menuMgr, viewer);
について、コンテキストメニューを外部に公開するときは必ず書くんですよね、と適当に理解していたのですが、ちゃんと調べてみました。ちなみに[[ここ:http://www.masatom.in/pukiwiki/index.php?Eclipse%2F%A5%D7%A5%E9%A5%B0%A5%A4%A5%F3%B3%AB%C8%AF%A4%CETIPS%BD%B8%2Forg.eclipse.ui.IViewActionDelegate%28%A5%DD%A5%C3%A5%D7%A5%A2%A5%C3%A5%D7%A1%A6%A5%E1%A5%CB%A5%E5%A1%BC%A5%D0%A1%BC%29#ef888ced]]にもまとめてありますが、このregisterContextMenuを記述すると''指定したメニューをビューのIDで外部に公開しますよ''という意味になります。


#contents

スニペット((イディオム。))として、こうやっときゃいいやってのはわかったんだけど、なんとなくスッキリしない。

ということで、viewerのところの引数をいろいろ変えてみて、どのような挙動をするのかテストしてみました。

**設定 [#s11d56bc]

#ref(pic.png)


上のように二つのviewerをビューに貼り付けて色々やってみる。
-viewer1: action1,action2を追加したビュー
-viewer2: getSite().setSelectionProvider(viewer2)したTableViewer

action1,action2はActionのanonymousクラス。。またviewer2は、setSelectionProviderの記述により「このビューのSelectionProviderはviewer2だよ」と宣言している。

**SelectionProviderから値をとってみる [#ya00b876]
-action1#runの処理: 
 ISelection selection = viewer.getSelection();
 System.out.println(selection.getClass().getName());
 System.out.println(selection);
つまりviewerから値をとって表示するだけ。


-action2#runの処理: 
 ISelectionProvider selectionProvider = getSite()
         .getSelectionProvider();
 System.out.println(selectionProvider.getSelection().getClass()
         .getName());
 System.out.println(selectionProvider.getSelection());
つまりビューのSelectionProviderから値をとって表示するだけ。


***結果 [#kc602909]
-action1#runの実行結果:  
 org.eclipse.jface.viewers.StructuredSelection
 [viewer1:a]
-action2#runの実行結果: 
 org.eclipse.jface.viewers.StructuredSelection
 [viewer2:a]

当たり前ですね。getSite().setSelectionProvider(viewer2)しているので「このビューのSelectionProviderから選択してるものちょうだい」といった場合、viewer2で選択されているものが取得できるわけですね。


**つぎにregisterContextMenuしてからやってみる [#xb98bbd7]
次に、
 getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);
してみる((律儀にgetSite().getId()書いてますが、getSite().registerContextMenu(menuMgr, viewer);と同じです))。特に挙動は変わらず。registする作業はプログラマティカルに追加したアクションには関係ないのかな((ここはようわかってない))???


**拡張ポイントのばあい [#wa286a51]
次に、拡張ポイントでポップアップを追加する。
 </viewerContribution>
       <viewerContribution id="nu.mine.kino.plugin.samples.rcp.viewerContribution3"
       targetID="nu.mine.kino.plugin.samples.views.ProviderSampleView">
      <action      ↑これはviewのIDではなく、 これ↓です。ねんのため
                   registerContextMenu(getSite().getId(), menuMgr, viewer1);
          class="nu.mine.kino.plugin.samples.rcp.Action5" icon="icons/sample.gif"
          id="nu.mine.kino.plugin.samples.rcp.action5" label="アクション5"
          menubarPath="additions"/>
 </viewerContribution>

IViewActionDelegateの実装クラスAction5を
 public class Action5 implements IViewActionDelegate {
   private ISelection selection;
   private IViewPart view;
   public void init(IViewPart view) {
     this.view = view;
   }
 
   public void run(IAction action) {
     System.out.println("selectionからとってみる");
     System.out.println(selection.getClass().getName());
     System.out.println(selection);
   }
 
   public void selectionChanged(IAction action, ISelection selection) {
     this.selection = selection;
     System.out.println("selectionからとってみる");
     System.out.println(selection.getClass().getName());
     System.out.println(selection);
   }
 }
とすると。。。

***結果1 [#r6d00f75]
まず getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);を呼ばない場合、いくら拡張ポイントでtargetID指定で追加してもこのターゲットIDでコンテキストを登録していないので、ポップアップにアクションが追加されません。合掌。

次に
 getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);
をしてからやってみると。。。


***結果2 [#k96784d5]
なんと
 selectionからとってみる
 org.eclipse.jface.viewers.StructuredSelection
 [viewer1:b]
となった。おもしろいのはビュー側で
 getSite().setSelectionProvider(viewer2);
として「このビューのSelectionProviderはviewer2だよ」と宣言しているにも関わらず、IViewActionDelegateの実装クラスselectionChangedには、viewer2ではなくviewer1が渡ってきているのだ。なるほど、
 getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);
の意味は''このコンテキストメニュー(menuMgr)をgetSite().getId()というtargetIDで公開するよ、そのときのSelectionProvider(selectionChangedの引数selectionを作るヤツ)はviewer1ですよ''という意味なんですね。


ではつぎに
 getSite().registerContextMenu(getSite().getId(), menuMgr, viewer2);
とした場合はどうなるか。この例はviewer2をregisterContextMenuしているので、拡張ポイントたちに対するSelectionProviderはviewer2となり、IViewActionDelegateの実装クラスはviewer2をリスンすることになります((つまりviewer2をクリックするとselectionChangedが反応する))。でも、このメニューmenuMgrはviewerの方にセットされているので、アクション自体はviewer1に表示される。つまり''viewer2をクリックするとselectionChangedが呼ばれるけど、viewer1のポップアップメニューに追加される''というわけわかんないことになります。こんなコトする必要はないですけど、仕組みはよく理解できました。


よってスニペットとしては
 getSite().registerContextMenu(getSite().getId(), menuMgr, getSite().getSelectionProvder());
よりも
 getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);
のように''menuMgrを追加したviewerを第3引数に設定する''のが間違いがないかなあ、という結論になりました。だってこのビューのSelectionProviderがmenuMgrを追加したビューワではない可能性があるからね。



ところで第三引数にnullをセットすると、拡張ポイントに対するSelectionProviderがnullなので、selectionChangedは呼ばれんだろうと思ったのですが、メニューからそのアクションを選択したとき、なぜかselectionChangedが呼ばれ、空の((nullの、ではない))selectionがセットされていた。ナゾだ。。actionインスタンスの方はViewPluginActionというdelegateだ。。これ以上深追いはいいや。。。





----
- uahaleuamorg -- [[uahaleuamorg]] &new{2014-10-29 (水) 12:43:49};
- uahaleuamorg -- [[uahaleuamorg]] &new{2014-10-29 (水) 12:44:12};
- uahaleuamorg -- [[uahaleuamorg]] &new{2014-10-29 (水) 12:44:31};
- uahaleuamorg -- [[uahaleuamorg]] &new{2014-10-29 (水) 12:44:54};
- uahaleuamorg -- [[uahaleuamorg]] &new{2014-10-29 (水) 12:45:13};
- dduydome -- [[dduydome]] &new{2014-10-31 (金) 02:37:03};
- dduydome -- [[dduydome]] &new{2014-10-31 (金) 02:37:23};
- dduydome -- [[dduydome]] &new{2014-10-31 (金) 02:37:43};
- dduydome -- [[dduydome]] &new{2014-10-31 (金) 02:38:04};
- dduydome -- [[dduydome]] &new{2014-10-31 (金) 02:38:24};
- mwomensmoncler -- [[mwomensmoncler]] &new{2014-11-03 (月) 13:16:50};
- mwomensmoncler -- [[mwomensmoncler]] &new{2014-11-03 (月) 13:17:13};
- mwomensmoncler -- [[mwomensmoncler]] &new{2014-11-03 (月) 13:17:34};
- mwomensmoncler -- [[mwomensmoncler]] &new{2014-11-03 (月) 13:17:57};
- mwomensmoncler -- [[mwomensmoncler]] &new{2014-11-03 (月) 13:18:21};

#comment

#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS