Top / Eclipse / プラグイン開発のTIPS集 / getSite().registerContextMenuを理解する

どうしても、

getSite().registerContextMenu(menuMgr, viewer);

の処理がいまいち理解できない。。スニペットしてこうやっときゃいいやってのはわかったんだけど、なんとなくスッキリしない。

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

設定

pic.png

上のように二つのviewerをビューに貼り付けて色々やってみる。

action1,action2はActionのanonymousクラス。。setSelectionProvider?の処理により「このビューのSelectionProvider?はviewer2だよ」と宣言している。

SelectionProvider?から値をとってみる

結果

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

つぎにregisterContextMenu?してからやってみる

次に、

getSite().registerContextMenu(getSite().getId(), menuMgr, viewer1);

してみる*1。特に挙動は変わらず。registする作業はプログラマティカルに追加したアクションには関係ないのかな*2???

拡張ポイントのばあい

次に、拡張ポイントでポップアップを追加する。

</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

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

次に

getSite().registerContextMenu(getSite().getId(), menuMgr, viewer);

をしてからやってみると。。。

結果2

なんと

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をリスンすることになります*3。でも、このメニュー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が呼ばれ、空の*4selectionがセットされていた。ナゾだ。。actionインスタンスの方はViewPluginAction?というdelegateだ。。これ以上深追いはいいや。。。


この記事は

選択肢 投票
おもしろかった 0  
そうでもない 0  

Top / Eclipse / プラグイン開発のTIPS集 / getSite().registerContextMenuを理解する

現在のアクセス:15055


*1 律儀にgetSite().getId()書いてますが、getSite().registerContextMenu?(menuMgr, viewer);と同じです
*2 ここはようわかってない
*3 つまりviewer2をクリックするとselectionChangedが反応する
*4 nullの、ではない

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