ほとんどの場合、ユーザーは、テキスト・フィールドやコンボ・ボックスなどのシンプルなフィールドにテキスト情報を入力することが予想されています。これらのフィールドを取り込むアプリケーション・コードは、一般にテーブルやツリーなどの複雑なウィジェットを取り込むコードよりもはるかに単純ですが、通常、これらの「シンプルな」フィールドはユーザーにとって負担が大きくなります。ユーザーは、どのフィールドがコンテンツを必要としているか、フィールドに有効なコンテンツが含まれているかどうか、およびどの選択が予想されているかを識別する必要があります。 JFace フィールド支援サポートは、ユーザーの入力タスクをガイドするクラスを提供します。
org.eclipse.jface.fieldassist パッケージは、2 つの方法で支援を行います。 装飾フィールドのサポートは、特定のフィールドのステータスについてユーザーに合図を出すイメージ装飾を含めることができるようにします。 コンテンツ・プロポーザル・サポートは、ユーザーにコンテンツ選択を提供するコンテンツ・アシスト・ポップアップを提供できるようにします。
装飾フィールドは、ウィンドウまたはダイアログに定義されているフィールドに隣接してイメージ装飾を配置できるようにします。装飾は、フィールドの 4 つの隅のいずれかに隣接して配置することができます。装飾フィールドの目的は、ビューアーと同様に、基本となるコントロールへのアクセスを提供しながら、SWT コントロールに機能を追加することです。 DecoratedField の API では、フィールドに隣接した装飾を追加したり、非表示にしたり、表示したりすることができます。基本となるコントロールへのアクセスが提供されているため、既存の SWT API を使用して、コンテンツ、色、フォントの設定など、基本となるコントロールに影響を与えることができます。
外部からは、装飾フィールドは単一コントロールのように振る舞います。内部では、装飾フィールドは、フィールドのレイアウトとその装飾を管理する複合コントロールを使用します。ほとんどの場合、これはクライアント・アプリケーションに影響を与えません。ただし、これは、装飾フィールドがコントロールを実際に作成する必要があることを意味します。例えば、以下のスニペットについて考えてみます。ここでは、アプリケーションがそのダイアログの 1 つの中にテキスト制御を作成します。
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); ...
このフィールドを装飾するには、以下の方法でフィールドを作成する必要があります。
... // Create a decorated field for a text control DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); ...
基本的なコントロールを作成するために使用された親とスタイル・ビットは、装飾フィールドの作成にも使用されています。コードの主な違いは、フィールドに必要な特定の種類のコントロールを作成する、 IControlCreator のインスタンスが使われていることです。テキスト・フィールドでは、クラス TextControlCreator を使用してコントロールを作成できます。ただし、 IControlCreator を実装し、コンボ・ボックスやスピナーなど、別の種類のコントロールをフィールド内に作成する柔軟性もあります。
いったん装飾フィールドが作成されると、フィールドの 4 つのロケーションの 1 つに装飾を追加できます。 SWT ロケーション定数は、装飾を配置する場所を指定するために使用されます。装飾を追加するには、装飾のイメージを定義する FieldDecoration、およびユーザーが装飾にカーソルを当てたときに表示される (オプションの) 説明テキストを指定する必要があります。
... // Create a field decoration and add it to the field Image image = JFaceResources.getImage("myplugin.specialimage"); FieldDecoration mySpecialDecoration = new FieldDecoration(image, "This field is special"); field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false); ...
ブール・パラメーターを使用して、コントロールにフォーカスがある場合だけ装飾を表示するのか、または常に表示するのかを指定します。この場合、装飾は常に表示されます。ただし、装飾を非表示にしたり、表示したりする必要がある場合もあります。以下のスニペットでは、既に作成済みの装飾を非表示にします。
... // Something has occurred that makes me want to hide the decoration field.hideDecoration(mySpecialDecoration); ...
装飾のイメージまたは説明が更新された場合は、装飾を再描画できるようにフィールドに通知される必要があります。
... // Something has made the field extra special mySpecialDecoration.setDescription("This field is extra-special"); field.updateDecoration(mySpecialDecoration); ...
ダイアログまたはウィンドウ内で装飾フィールドをレイアウトする場合は、基本となるシンプルなコントロールよりも、フィールドのレイアウト・コントロールをレイアウトする必要があります。テキスト・コントロールを作成するコードについて再度考えてみます。テキスト・コントロールをレイアウトすると、アプリケーションはレイアウト・データをコントロール上に設定します。
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Set the layout data GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT); text.setLayoutData(data); ...
装飾フィールドをレイアウトする場合、アプリケーションはレイアウト・データをフィールドのレイアウト・コントロール上に置く必要があります。希望のレイアウトに沿うように、装飾のサイズに合わせてフィールドのサイズを調整する必要がある場合があります。
... // Create a decorated field for a text control DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); // Set the layout data GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH + FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT); field.getLayoutControl().setLayoutData(data); ...
フィールド支援サポートは、特定のダイアログまたはウィンドウ内で装飾フィールドのみを使用することを要求したり、想定したりすることはありません。ただし、装飾フィールドをシンプルなコントロールと混ぜ合わせて使用すると、ご使用のウィンドウのレイアウトがやや複雑になります。装飾フィールドと非装飾フィールドを位置合わせするには、装飾の幅により発生するインデントを考慮する必要があります。装飾の幅は、単にそのイメージの幅です。ただし、幅が異なる装飾を使用している場合、問題はより複雑になります。このような場合、ご使用の装飾をすべて FieldDecorationRegistry に登録することで、問題を単純化することができます。
フィールド装飾レジストリーを使用すると、ご使用のフィールド装飾を登録し、ストリング ID を使用してアクセスできるようになります。これは、アプリケーション全体で使用される装飾を参照する際に便利です。他のプラグインで使用できるようにするために、装飾 ID を公開する API を定義することができます。装飾の登録では、それらの装飾内のイメージのライフ・サイクルが管理されないことに注意してください。アプリケーションで、これらのイメージの管理方法を決定できます。例えば、イメージのライフ・サイクルを登録して管理するために JFace イメージ・レジストリーを使用することができます。あるいは、アプリケーションで、要求時にイメージを作成し、不要になったときに廃棄するようにすることもできます。 FieldDecorationRegistry の登録メソッドの javadoc では、装飾を登録する際にイメージを指定できるさまざまな方法について説明しています。
装飾をフィールド装飾レジストリーに登録することで、装飾 (および非装飾) フィールドを組み合わせて使用する際に、レイアウト・プロセスを単純化することもできます。デフォルトでは、装飾フィールドはフィールド装飾レジストリーを参照して装飾の最大幅を判別し、すべての装飾でこの幅を使用するようにします。これは、特定の装飾の幅に関係なく、すべての装飾フィールドが正しく位置合わせされることを意味します。非装飾フィールドを位置合わせするために、 FieldDecorationRegistry プロトコルを使用して、最大の装飾の幅にアクセスして必要なインデントを作成できます。
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Set the layout data GridData data = new GridData(); data.horizontalAlignment = SWT.FILL; data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); text.setLayoutData(data); ...
フィールド支援サポートは装飾の使用方法に関する指示を行いませんが、レジストリーは、フィールドの特定の状態を示すためにアプリケーションが使用できる標準の装飾も定義します。例えば、以下のスニペットでは、必須フィールドに標準装飾を使用しています。
... // Create a decorated field with a required field decoration. DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); FieldDecoration requiredFieldIndicator = FieldDecorationRegistry.getDefault(). getFieldDecoration(FieldDecorationRegistry.DEC_REQUIRED); field.addDecoratedField(requiredFieldIndicator, SWT.BOTTOM | SWT.LEFT, false); ...
フィールドを装飾するほか、アプリケーションは、フィールドのプロポーザル・ポップアップをアクティブにするコンテンツ・プロポーザル支援を提供することができます。この振る舞いを実現するには、 ContentProposalAdapter を任意の制御にインストールする場合があります。以下のスニペットでは、テキスト制御にコンテンツ・プロポーザル・アダプターをインストールしています。アプリケーションが直接作成した制御でも、装飾フィールドから取得した制御でも、このテキスト制御として使用できることに注意してください。
... autoActivationCharacters = new char[] { '#', '(' }; keyStroke = KeyStroke.getInstance("Ctrl+Space"); // assume that myTextControl has already been created in some way ContentProposalAdapter adapter = new ContentProposalAdapter( myTextControl, new TextContentAdapter(), new SimpleContentProposalProvider(new String [] {"ProposalOne", "ProposalTwo", "ProposalThree"}), keyStroke, autoActivationCharacters);
ユーザーがポップアップでプロポーザルを選択する場合に、コントロールのコンテンツを取得および設定するには、アダプターが、特定の種類のコントロールのコンテンツを取得および設定できる IControlContentAdapter のインスタンスを備えている必要があります。テキスト・フィールドでは、 TextContentAdapter クラスを使用できます。ただし、 IControlContentAdapter を実装して、コンテンツ・プロポーザル・アダプターを任意の種類のコントロールと共に使用することもできます。
コンテンツ・プロポーザル・アダプターを作成する場合は、プロポーザル自体が取得される IContentProposalProvider のインスタンスも指定する必要があります。このプロバイダーは、コンテンツ・プロポーザルの配列を戻します。プロポーザル自体は、プロポーザルの詳細記述などの他の情報に加えて、プロポーザルのラベルおよびコンテンツを取得できる IContentProposal のインスタンスとして指定されます。
上記の例では、 SimpleContentProposalProvider が使用されています。このプロバイダーは、ストリングの単純配列をコンテンツ・プロポーザルとして指定することによって定義されます。単純なプロバイダーは、各ストリングを予期される IContentProposal にマップするために必要なプロトコルを実装します。 IContentProposalProvider の柔軟性により、拡張機能を備えたプロポーザル・プロバイダーを実装できます。これらの拡張機能としては、コントロールのコンテンツに基づいたプロポーザルのフィルタリング、挿入される実際のコンテンツの代わりとなるポップアップの説明ラベルの提供、およびプロポーザルの挿入後の予期されるカーソル位置の指定などがあります。『フィールド支援の例』で、拡張使用について IContentProposalProvider インプリメンターを参考にしてください。
コンテンツ・プロポーザル・アダプターの基本定義には、プロポーザルが提供されるコントロール、コントロールのコンテンツを変更するコンテンツ・アダプター、およびポップアップのプロポーザル・リストを定義するプロポーザル・プロバイダーが含まれることは既に説明しました。これらの基本定義に加えて、コンテンツ・プロポーザル・アダプターを構成できる多数の方法があります。
JFace レベルのフィールド支援サポートには、アプリケーションがフィールドの装飾方法およびフィールド・コンテンツにプロポーザルを表示する方法を決定する際に高い柔軟性があります。これは、スタンドアロン JFace アプリケーションまたはスタンドアロン・リッチ・クライアント・アプリケーションにとって望ましいことです。ただし、ご使用のアプリケーションが、Eclipse SDK やサード・パーティーのプラグインなどの他のプラグインとの統合を意図している場合、他のプラグインと一貫性のある方法でフィールド支援サポートを使用したい場合があります。ワークベンチは、特定の種類の相互作用に対してフィールド支援を使用するユーティリティー・クラスを定義します。
例えば、クラス ContentAssistField は、コンテンツ・アシストが使用可能であることをユーザーに知らせる電球型の装飾を含むフィールドを作成します。また、コンテンツ・アシスト・スタイルの挿入を行うために、コンテンツ・プロポーザル・アダプターを構成します。最後に、ワークベンチ・レベルのコンテンツ・アシスト・コマンドのハンドラーを提供し、ユーザーが、ワークベンチのキー・バインディングで指定されたキー・ストロークまたはトリガー・シーケンスを呼び出したときに、コンテンツ・プロポーザル・ポップアップが開かれるようにします。これらのユーティリティー・クラスの詳細については、 org.eclipse.ui.fieldassist パッケージを参照してください。
このパッケージは、ワークベンチがそのフィールド支援の使用を拡張し、特定のフィールド状態に対する装飾の使用を標準化するにつれて、発展することが期待されています。