// 下階層用テンプレート #topicpath ---- //ここにコンテンツを記述します。 #contents さて、Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable の続きです。 さっきのように、ContactクラスがPlatformObjectを拡張している場合は、 org.eclipse.core.runtime.IAdaptable インタフェース org.eclipse.core.runtime.PlatformObject オブジェクト org.eclipse.core.runtime.IAdapterFactory ファクトリ を使ってViewに表示ができました。今度はModelオブジェクトがIAdaptableやPlatformObjectを実装していない場合はどうするか、です。。通常このような場合が多いですよね。モデルをEclipse依存にしたくないですしね。 ***モデル [#u660bd10] モデルは先のクラス構成で、ContactがPlatformObjectを拡張していない、一般的なクラスであると仮定します。 #ref(model.png) ***org.eclipse.core.runtime.adapters拡張ポイント [#w41962c2] こたえはやはりorg.eclipse.core.runtime.adapters拡張ポイントみたいです。 <extension point="org.eclipse.core.runtime.adapters"> <factory adaptableType="org.eclipsercp.hyperbola.model.Contact" class="org.eclipsercp.hyperbola.model.HyperbolaAdapterFactory"> <adapter type="org.eclipse.ui.model.IWorkbenchAdapter"/> </factory> </extension> このように定義しておくと、Contactのインスタンスelementに対して、 Platform.getAdapterManager().loadAdapter (element, IWorkbenchAdapter.class.getName()); ↑adaptableType ↑<adapter type="org.eclipse.ui.model.IWorkbenchAdapter"/> というメソッドがよばれたときに、 IAdapterFactory adapterFactory = new HyperbolaAdapterFactory(); Platform.getAdapterManager().registerAdapters(adapterFactory,Contact.class); が自動的に行われます。でメソッドの返り値が IAdapterFactory#getAdapter(element, IWorkbenchAdapter.class); になります。 つまりContactがPlatformObjectではないにもかかわらず、IAdapterFactoryを用いて IWorkbenchAdapter adapter=(IWorkbenchAdapter) Contact.getAdapter(IWorkbenchAdapter.class); の様なことができるわけですね。これと IAdapterFactory adapterFactory = new HyperbolaAdapterFactory(); Platform.getAdapterManager().registerAdapters(adapterFactory,Contact.class); IWorkbenchAdapter adapter = (IWorkbenchAdapter)adapterFactory.getAdapter(IWorkbenchAdapter.class); は等価でしたね。 ***ちょっとまとめ [#e297a645] まとめると -あるモデルがある -あるモデルに対してgetAdapterして別のオブジェクトを取得したい -plugin.xmlに <extension point="org.eclipse.core.runtime.adapters"> <factory adaptableType="あるモデルのクラス名" class="IAdapterFactoryの実装クラス名"> <adapter type="別のオブジェクトのクラス名"/> </factory> </extension> と定義しておく -IAdapterFactoryの実装クラスで public Object getAdapter(Object adaptableObject, Class adapterType); public Class[] getAdapterList(); をoverrideする -public Object getAdapter(Object adaptableObject, Class adapterType);は adaptableObjectはあるモデルのクラス名 adapterTypeは別のオブジェクトのクラス名 だった場合は「別のオブジェクトのクラス」を返す、という処理を書く -public Class[] getAdapterList();は「別のオブジェクトのクラス」を返すようにしておく となるわけです。つまり、ある一般的なクラスに対して、IAdaptableでないにも関わらず動的にgetAdapterが呼べる仕組みということですね。まだ、あたまがまとまってませんが、ものすごい事のような気がしてきました。 ***さて、つづき [#ldaa64ed] さて、Viewerの続きです。ContactはもはやPlatformObjectではないため当然IAdaptableでもありません。これだけだとBaseWorkbenchContentProviderの protected IWorkbenchAdapter getAdapter(Object element) { if (!(element instanceof IAdaptable)) { return null; } return (IWorkbenchAdapter) ((IAdaptable) element) .getAdapter(IWorkbenchAdapter.class); } は当然nullになってしまうので、拡張クラスを作ってOverrideします。 public class HogeContentProvider extends BaseWorkbenchContentProvider { protected IWorkbenchAdapter getAdapter(Object element) { ↑この引数elementはモデル要素: Contact,ContactEntry,ContactGroupでした IWorkbenchAdapter adapter = null; // モデルが、IAdaptableならばそのまま使う if (element instanceof IAdaptable) { adapter = getAdapter(element); } // モデルが、一般的なオブジェクトならば、さっきの動的ローディングをつかう。 if (element != null && adapter == null) { adapter = (IWorkbenchAdapter) Platform.getAdapterManager() .loadAdapter(element, IWorkbenchAdapter.class.getName()); } // この返り値adapterは、org.eclipsercp.hyperbola.model.HyperbolaAdapterFactory // のgetAdapter(element,IWorkbenchAdapter.class);になるんでしたね。 return adapter; } } Viewerにはこのコンテンツプロバイダをセットすることで、先と同じ結果が得られます。 当然、Viewでorg.eclipsercp.hyperbola.model.HyperbolaAdapterFactoryをnewする必要もないし、当然register,unregisterも必要ないです。モデルオブジェクトもPlatformObjectを拡張している必要もありません。 、、、、ここまでやって、コンテンツプロバイダやラベルプロバイダはIWorkbenchAdapterを使わない一般的なやり方の方がいいような気がしますね。よくわかってないだけかも知れないけど。。 あ、当然ラベルプロバイダも書き換える必要があります。この書きかえ方が...またようわからん。。WorkbenchLabelProvider#getAdapterはfinalだし。。。。じぶんで書くしかないのかなぁ。。 ***関連リンク [#c3b6a9f0] #ls2(Eclipse/プラグイン開発のTIPS集/org.eclipse.core.runtime.IAdaptable) ---- この記事は #vote(おもしろかった[5],そうでもない[0]) #vote(おもしろかった[6],そうでもない[0]) -ここに書いた情報は、まだあってるかあやしいですよ。。ごちゅうい。。 -- [[きの]] &new{2006-03-27 16:47:16 (月)}; #comment #topicpath SIZE(10){現在のアクセス:&counter;}