|
さて、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依存にしたくないですしね。 モデル †モデルは先のクラス構成で、ContactがPlatformObject?を拡張していない、一般的なクラスであると仮定します。 org.eclipse.core.runtime.adapters拡張ポイント †こたえはやはり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); は等価でしたね。 ちょっとまとめ †まとめると
となるわけです。つまり、ある一般的なクラスに対して、IAdaptableでないにも関わらず動的にgetAdapterが呼べる仕組みということですね。まだ、あたまがまとまってませんが、ものすごい事のような気がしてきました。 さて、つづき †さて、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だし。。。。じぶんで書くしかないのかなぁ。。 関連リンク †
この記事は
現在のアクセス:13679 |