Top / Eclipse / プラグイン開発のTIPS集 / org.eclipse.ui.ISelectionListener

オブジェクトを選択したイベントに反応するリスナ

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();
  ... 選択されたオブジェクトにキャストしていろいろ....
}

などの様にして選択されたオブジェクトを取得します。

リスナをワークベンチに登録・削除する

さて、このリスナのインスタンスは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が選択されたことを通知してもらえません*1。これだと困るので、とりあえず、HogeView?のcreatePartControl?の最後で、

selectionChanged(null, getSite().getPage().getSelection());

と直接メソッドをコールしました。。。ほかにいい解法あったらだれか教えてください。

オブジェクトが選択されるということって

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

さて答えはプロパティビューなどでも出てきていた

getSite().setSelectionProvider(viewer);

でした。なんとなくモヤモヤと実行していましたがすっきりしました。Eclipseはなんかを選択したというイベントをビューやエディタなどのpartごとに管理していて、getSite().setSelectionProvider?(viewer);を実行することで「このビュー*2の選択されたというイベントを発行するクラスはviewerですよ」と宣言してるわけですね。getSite()の返り値のIWorkbenchPartSite?インタフェースの理解*3と、選択イベントの発生がビューごとに管理されている、というのが理解できれば、当たり前でしたね。setSelectionProvider?というメソッド名もスッキリしました。「選択したものやイベントを供給してくれるクラス」をsetしたわけですね。なるほど。

2006/5/12追記
調べたそばから、非常にわかりやすい説明がeclipse.orgに出てました。Eclipse Workbench: Using the Selection Service

TIPS集

あるパートだけをListenする

public void addSelectionListener(String partId, ISelectionListener listener)

をメソッドは、partIdのビュー・エディタだけに反応するようにリスナを追加します*4


この記事は

選択肢 投票
おもしろかった 9  
そうでもない 1  
  • 複数のViewerがあってどちらの情報もListenしたい場合はISelectionProvider?として何をセットするのかなあ??自分で定義するのかな?? -- きの? 2006-04-09 09:29:43 (日)
  • 自分で定義して、とりあえずできることまでは確認できました。 -- きの? 2006-05-12 19:22:05 (金)

Top / Eclipse / プラグイン開発のTIPS集 / org.eclipse.ui.ISelectionListener

現在のアクセス:12248


*1 遡及して教えてくれーって感じ
*2 getSite()で返されるインスタンスIWorkbenchPartSite?は、ビューと一対一対応していて、ビューの情報を管理するインスタンスでした。
*3 IWorkbenchPartSite?はPart(Viewとか)の情報を管理するインタフェース
*4 partIdはたぶんビューのIDやエディタのID。。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-04-09 (金) 10:27:42 (5293d)