// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
どうしても、
 getSite().registerContextMenu(menuMgr, viewer);
の処理がいまいち理解できない。。スニペットしてこうやっときゃいいやってのはわかったんだけど、なんとなくスッキリしない。

ということで、テストしてみました。

**設定 [#s11d56bc]

#ref(pic.png)


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

action1,action2はActionのanonymousクラス。。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 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, viewer);を呼ばない場合、いくら拡張ポイントでtargetID指定で追加してもこのターゲットIDでコンテキストを登録していないので、ポップアップにアクションが追加されません。合掌。

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


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


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


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



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





----
この記事は
#vote(おもしろかった,そうでもない)

#comment
#topicpath


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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS