ビューアー

SWT ウィジェットを使用することによって、ビュー、エディター、ウィザード、 およびダイアログなどのワークベンチ UI による追加機能を直接インプリメントできるにもかかわらず、 ビューアーを使用するのはなぜでしょうか?  

ビューアーによって、ユーザー・モデル・オブジェクトの使用中でも、 ユーザーは、ウィジェットを作成することができます。 SWT ウィジェットを直接使用する場合には、 ユーザーは、ユーザー・オブジェクトを SWT が必要とするストリングおよびイメージに変換する必要があります。  ビューアーは、SWT ウィジェットのアダプターとして機能することによって、 ユーザーが本来ユーザー自身でインプリメントする必要があるウィジェット・イベントの処理を共通コードの処理によって行います。 

本書でビューアーを最初に取り扱っている箇所は、ReadmeSectionsView にある README ツールのビューの追加機能です。

   public void createPartControl(Composite parent) {
      viewer = new ListViewer(parent);
      ...
   }
注:  ビューアーは、ワークベンチのビューとエディターの両方に インプリメンテーションを提供するために使用できます。ビューアーという用語は、ビューのインプリメントにのみ役立つということを意味しているわけではありません。例えば TextViewer は、 多数のワークベンチおよびプラグインのエディターにおけるインプリメンテーションに使用されます。

標準ビューアー

JFace は、SWT のほとんどの重要なウィジェットに対してビューアーを提供します。ビューアーは、リスト、ツリー、テーブル、およびテキストのウィジェットに対して、 最も一般的に使用されています。 

それぞれのビューアーは、1 つの SWT ウィジェットに関連付けられています。このウィジェットは、 コンビニエンス・ビューアー・コンストラクターの親コンポジットを提供することによって暗黙的に作成されるか、 または、親コンポジットを作成し、 そのコンポジットをそのコンストラクターのビューアーに提供することによって明示的に作成することができます。

リスト指向のビューアー

リスト、ツリー、およびテーブルは、ユーザーの観点から見ると、オブジェクトの集合、選択、ソート、およびフィルター操作など、多数の共通機能を共有しています。 

これらのビューアーは、ドメイン・オブジェクト (エレメントと呼ばれています) のリストを保持し、 対応する SWT ウィジェットにそのリストの内容を表示します。リスト・ビューアーは、 リスト内のすべてのエレメントからのテキスト・ラベルの取得方法を認識しています。  このビューアーは、ビューアー上で設定可能な ILabelProvider からラベルを取得します。  リスト・ビューアーは、ウィジェット・コールバックから、 ビューアー・クライアントが認識するエレメントの世界にマップする方法を認識しています。

プレーン SWT ウィジェットを使用するクライアントは、SWT レベルで操作を行う必要があります。 このレベルでは、項目はストリングで、ほとんどの場合、イベントはストリングのリスト内の索引に関連しています。 ビューアーは、高度なセマンティクスを提供します。クライアントには、クライアントがビューアーに提供したエレメントを使用して、 そのリストの選択および変更が通知されます。 ビューアーは、索引をエレメントにマップし戻すためのすべての面倒な作業を処理し、 この結果、オブジェクトのフィルター操作されたビューは調整され、必要であれば再度ソートされます。

フィルター操作およびソート機能の処理は、 そのビューアーにビューアー・ソーター (ViewerSorter) および / またはビューアー・フィルター (ViewerFilter) を 指定することによって行います。(この指定は、リスト・ビューアーだけでなく、 ツリー・ビューアーおよびテーブル・ビューアーに対しても行うことができます。) クライアントが行う必要のあることは、 リスト内のオブジェクトを比較またはフィルター操作できるクラスを指定するだけです。 ビューアーは、指定された順序およびフィルター操作に従ってリストを取り込み、 エレメントの追加および除去時にその順序およびフィルター操作を保持する作業の詳細を処理します。

ビューアーは、クライアントによって拡張されるようには設計されていません。 ビューアーのカスタマイズは、 ユーザー独自のコンテンツおよびラベルのプロバイダーを使用して構成できます。

ListViewer は、 リスト内のエレメントを SWT リストのコントロールにマップします。

TreeViewer は、SWT ツリー・ウィジェット内の階層オブジェクトを表示します。このビューアーは、項目の拡張表示および縮小表示の詳細を処理します。別の SWT ツリー制御 (プレーン・ツリー、テーブル・ツリー、チェック・ボックス・ツリー) に対して、いくつかの異なる種類のツリー・ビューアーがあります。

TableViewer は、リスト・ビューアーに非常に似ていますが、 テーブルの各エレメントの情報の複数のカラムを表示する機能を追加します。  テーブル・ビューアーは、セルの編集についての概念を導入することによって、SWT テーブル・ウィジェットの機能を大幅に拡張します。 特別なセル・エディターにより、ユーザーはコンボ・ボックス、ダイアログ、またはテキスト・ウィジェットを使用して、 テーブル・セルを編集できます。 テーブル・ビューアーは、ユーザーの編集で必要な時に、これらのウィジェットの作成および配置を処理します。  この処理は、TextCellEditor および CheckboxCellEditor などの CellEditor クラスを使用して行います。 仮想テーブルは、表示される場合にのみデータが取り込まれ、テーブル・ビューアーは、実際に作成されたものに関係なく、指定された数の結果のみを実行します。 データベース "lazily" は JIT を要求し、あらかじめ設定された数のみを同時に照会します。

テキスト・ビューアー

テキスト・ウィジェットには、ダブルクリックの振る舞い、 元に戻す、色、索引または行によるナビゲートなどの多数の共通セマンティクスがあります。  TextViewer は、SWT StyledText ウィジェットに対するアダプターです。 テキスト・ビューアーは、クライアントへの文書モデルを提供し、 テキスト・ウィジェットによって提供されたスタイル・テキスト情報への文書の変換を管理します。

テキスト・ビューアーについて詳しくは、『ワークベンチ・エディター』で説明されています。

ビューアーのアーキテクチャー

ビューアーを理解するには、ビューアーの入力エレメント、その内容、その選択、およびビューアーが取り扱うウィジェットに実際に表示される情報の間の関係を理解している必要があります。

入力エレメント

入力エレメントは、ビューアーが表示する (または編集する) メイン・オブジェクトです。 ビューアーの観点からは、入力エレメントがどのようなオブジェクトであってもかまいません。 ビューアーは、入力エレメントによって特定のインターフェースがインプリメントされることは前提にしていません。(この理由は、コンテンツ・プロバイダーを理解するとすぐにわかります。)

ビューアーは、入力エレメントの変更を処理できる必要があります。新規入力エレメントがビューアーに設定されると、新規エレメントに応じてそのウィジェットを再度取り込み、直前の入力エレメントとの関連付けを解除します。入力エレメントのリスナーとして登録し、 そのエレメントに基づいてウィジェットを取り込むためのセマンティクスは、それぞれのビューアーごとに異なります。

コンテンツ・ビューアー

コンテンツ・ビューアーは、その入力エレメントから情報を取得するための定義に従ったプロトコルを持つビューアーです。 コンテンツ・ビューアーは次の 2 つの専門化された helper クラス、 IContentProvider および ILabelProvider を使用して、 これらクラスのウィジェットを取り込み、入力エレメントの情報を表示します。

IContentProvider は、 コンテンツ・プロバイダーを入力エレメントと関連付け、入力エレメントの変更を処理する、基本的なライフ・サイクル・プロトコルを提供します。 より専門化されたコンテンツ・プロバイダーが、他の種類のビューアーに対してインプリメントされます。最も一般的なコンテンツ・プロバイダーは、 IStructuredContentProvider です。このプロバイダーは、 入力エレメントが指定されたオブジェクト・リストを提供します。このリストは、リスト、テーブル、またはツリーなどのリスト形式のビューアーで使用されます。 一般的に、コンテンツ・プロバイダーは、入力エレメントおよびそれに対応するビューアー・コンテンツ間のマップ方法を認識しています。

ILabelProvider はさらに 1 歩先を進んでいます。ビューアーのコンテンツ (入力エレメントおよびコンテンツ・プロバイダーから派生した) を指定されているため、 このプロバイダーは、ビューアーでコンテンツの表示に必要な名前およびアイコンなどの特定の UI エレメントを生成できます。ラベル・プロバイダーは、アイコンの同一のインスタンスをビューアー内のすべての類似の型に対して使用するため、アイコン・リソースの節約に役立ちます。

:  特定のコンテンツおよびラベル・プロバイダーのインスタンスは、複数のビューアー間で共用されるようには設計されていません。すべてのユーザーのビューアーが、同じ型のコンテンツまたはラベル・プロバイダーを使用していたとしても、 それぞれのビューアーはそのプロバイダー・クラス固有のインスタンスで初期化しなければなりません。 プロバイダー・ライフ・サイクル・プロトコルは、プロバイダーおよびそのビューアーが 1 対 1 の関係で設計されています。

ビューアーは、入力エレメント、コンテンツ・プロバイダー、およびラベル・プロバイダーによって、 ウィジェットの取り込みに関する大部分のインプリメンテーションの詳細を隠すことができます。ビューアーのクライアントが考慮しなければならないことは、 ビューアーに適切な種類の入力およびコンテンツ・プロバイダーを取り込むということだけです。ラベル・プロバイダーは、ビューアー・コンテンツから UI 情報を派生させる方法を認識している必要があります。

ラベル・プロバイダーは、単なるテキストおよびイメージ以外のものを表示できます。JFace には、最も一般的な追加機能をサポートする複数のクラスおよびインターフェースが用意されています。 次のクラスは、TableViewer、AbstractTreeViewer、および TableTreeViewer でサポートされています。

Eclipse 3.1 以降は、2 つの点に関して (色およびフォントを設定する独自のラベル・プロバイダーまたはデコレーター) ビューの色に影響が及ぶ可能性があります。 一般に、ラベル・プロバイダーの色およびフォント・サポートを使用する方法を推奨します。デコレーターは特定のタイプを表示するすべてのビューに影響を与えるためです。 色またはフォント・デコレーターを使用する場合は、「色とフォント」設定ページで値を設定できることを確認してください。

ビューアーおよびワークベンチ

ビューアー、コンテンツ・プロバイダー、およびラベル・プロバイダーが提供する柔軟性は、ワークベンチがこれらプロバイダーを使用する方法を確認することで理解できます。

WorkbenchContentProvider は、入力エレメントからのコンテンツを、このプロバイダーの子に照会することによって取得する構造化されたコンテンツ・プロバイダーです。 アダプターの概念が、汎用機能をインプリメントするために、再度使用されます。入力エレメントからのエレメント・リストが照会されると、 WorkbenchContentProvider は その入力エレメントに対する IWorkbenchAdapter を取得します。IWorkbenchAdapter が その入力エレメントに対して登録されている場合には、 コンテンツ・プロバイダーはそのエレメントがその子に対して照会される場合があるということを前提にすることができます。  WorkbenchContentProvider も、 ワークスペースが変わった時に、その時点のビューアーを保持するために必要な作業を行います。 

WorkbenchLabelProvider は、そのテキストおよびイメージを検索するために、 オブジェクトから IWorkbenchAdapter を取得するラベル・プロバイダーです。ラベル・プロバイダーの概念は、 単一のラベル・プロバイダーにビューアーで共通で使用されるイメージのキャッシュを許可するため、特にワークベンチ・オブジェクトで役に立ちます。例えば、 一度 WorkbenchLabelProviderIProject で使用するイメージを取得すると、 そのイメージをキャッシュして、そのビューアーで表示されているすべての IProject オブジェクトに対して使用できます。

共通アダプター IWorkbenchAdapter を定義して、多くのプラットフォームの型に対してこのアダプターを登録することによって、 これらの型が、型が含まれている共通ビューアーおよびワークベンチ・ビューの多くで正しく表示できるようになります。