// 下階層用テンプレート
#topicpath
----
#contents

** オブジェクトを選択したイベントに反応するリスナ [#h45d0c58]
org.eclipse.ui.ISelectionListener はユーザのオペレーションのうち「オブジェクトを選択した」というオペレーションをListenするリスナです。「あるビューでオブジェクトを選択した」などのイベントに反応します。インタフェースは単純で

 public interface ISelectionListener {
   public void selectionChanged(IWorkbenchPart part, ISelection selection);
 }

のみですね。メソッド引数のpartは「オブジェクトを選択した」イベントを発生させた、ビューやエディタへの参照です。selectionは選択されたオブジェクトを保持するインスタンスで、selectionChangedないで
 if (selection instanceof IStructuredSelection) {
   IStructuredSelection sselection = (IStructuredSelection) selection;
   Object firstElement = sselection.getFirstElement();
   ... 選択されたオブジェクトにキャストしていろいろ....
 }
などの様にして選択されたオブジェクトを取得します。



***リスナをワークベンチに登録・削除する [#xfaf5454]
さて、このリスナのインスタンスはorg.eclipse.ui.ISelectionServiceインタフェースのメソッド
 public void addSelectionListener(ISelectionListener listener);
 public void removeSelectionListener(ISelectionListener listener);
でワークベンチに登録・解除されます。ISelectionServiceってあまり聞き慣れないインタフェースだと思いましたが、 org.eclipse.ui.IWorkbenchPage がextendsしています。つまりこのリスナの使い方としては、ビューなどでこのリスナをimplementsして、ビュー内で
 getSite().getPage().addSelectionListener(this);
 getSite().getPage().removeSelectionListener(this);
などとすればよさそうです。典型的なのは、ViewPartの拡張クラスで
 public void init(IViewSite site) throws PartInitException {
   super.init(site);
   site.getPage().addSelectionListener(this);
 }
 public void dispose() {
   super.dispose();
   getSite().getPage().removeSelectionListener(this);
 }
とするんでしょうか。




また、これだと''「一回このビューが表示されるまでワークベンチに登録されない」''という状態になっちゃいます。たとえば
-HogeViewがあってこのビューはどっかで選択された、Fugaというモデルオブジェクトを表示したい
-HogeViewはパースペクティブAに配置されている
-あるパースペクティブBで、Fugaが選択された

という場合ですが、この時パースペクティブAに切り替えるとHogeViewはこの時にinitされて、そのメソッドでワークベンチにリスナとして登録されるため、Fugaが選択されたことを通知してもらえません((遡及して教えてくれーって感じ))。これだと困るので、とりあえず、HogeViewのcreatePartControlの最後で、
 selectionChanged(null, getSite().getPage().getSelection());
と直接メソッドをコールしました。。。ほかにいい解法あったらだれか教えてください。







*** オブジェクトが選択されるということって [#n8bd69e6]
さて、オブジェクトが選択されたときにそれをリスンする方法はこれでOKですね。ではいままで「オブジェクトを選択したばあい」と軽くいってきましたが、そもそも「オブジェクトが選択されたというイベント」はどう発生させるのでしょうか。ビューに配置された○○Viewerなどでオブジェクトを選択しても、タダではイベントは発生しませんね。

さて答えは[[プロパティビュー>Eclipse/プラグイン開発のTIPS集/プロパティシートを使う]]などでも出てきていた
 getSite().setSelectionProvider(viewer);
でした。なんとなくモヤモヤと実行していましたがすっきりしました。''Eclipseはなんかを選択したというイベントをビューやエディタなどのpartごとに管理していて、getSite().setSelectionProvider(viewer);を実行することで「このビュー((getSite()で返されるインスタンスIWorkbenchPartSiteは、ビューと一対一対応していて、ビューの情報を管理するインスタンスでした。))の選択されたというイベントを発行するクラスはviewerですよ」と宣言してるわけですね。getSite()の返り値のIWorkbenchPartSiteインタフェースの理解((IWorkbenchPartSiteはPart(Viewとか)の情報を管理するインタフェース))と、選択イベントの発生がビューごとに管理されている、というのが理解できれば、当たり前でしたね。setSelectionProviderというメソッド名もスッキリしました。「選択したものやイベントを供給してくれるクラス」をsetしたわけですね。なるほど。''

:2006/5/12追記|調べたそばから、非常にわかりやすい説明がeclipse.orgに出てました。[[Eclipse Workbench: Using the Selection Service:http://www.eclipse.org/articles/Article-WorkbenchSelections/article.html]]




**TIPS集 [#na2593fd]
***あるパートだけをListenする [#a518ed52]
 public void addSelectionListener(String partId, ISelectionListener listener)
をメソッドは、partIdのビュー・エディタだけに反応するようにリスナを追加します((partIdはたぶんビューのIDやエディタのID。。))。


















----
この記事は
#vote(おもしろかった[8],そうでもない[1])
#vote(おもしろかった[9],そうでもない[1])
-複数のViewerがあってどちらの情報もListenしたい場合はISelectionProviderとして何をセットするのかなあ??自分で定義するのかな?? -- [[きの]] &new{2006-04-09 09:29:43 (日)};
-自分で定義して、とりあえずできることまでは確認できました。 -- [[きの]] &new{2006-05-12 19:22:05 (金)};

#comment
#topicpath


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

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