Feldunterstützung

Ein Benutzer muss häufig Textinformationen in einem einfachen Feld wie einem Textfeld oder einem kombinierten Feld eingeben. Obwohl der Anwendungscode, der diese Felder mit Werten füllt, generell viel einfacher als der Code für das Füllen eines komplexen Fensterobjektes (z. B. eine Tabelle oder eine Baumstruktur) ist, sind diese "einfachen" Felder für den Benutzer mit größeren Schwierigkeiten verbunden. Der Benutzer muss erkennen, in welchen Feldern Inhalt erforderlich ist, ob ein Feld gültigen Inhalt enthält und welche Auswahlmöglichkeiten erwartet werden. Die JFace-Feldunterstützung bietet Klassen, mit deren Hilfe Sie den Benutzer durch die Eingabetasks führen können.

Das Paket org.eclipse.jface.fieldassist stellt die Unterstützung auf zwei Wegen bereit. Mit der Unterstützung für mit Dekoratoren versehene Felder können Sie Imagedekorationen aufnehmen, die dem Benutzer den Status eines bestimmten Feldes erläutern. Die Unterstützung für Inhaltsvorschläge ermöglicht es Ihnen, ein Dialogfenster der Unterstützung für Inhalt bereitzustellen, das Inhaltsoptionen für den Benutzer zur Verfügung stellt.

Mit Dekoratoren versehene Felder

Durch Felder, die mit Dekoratoren versehen sind, können Sie Imagedekorationen neben Feldern platzieren, die in einem Fenster oder einem Dialog definiert sind. Dekorationen können an allen vier Ecken eines Feldes angeordnet werden. Wie Anzeigefunktionen dienen mit Dekoratoren versehene Felder dazu, die Funktionalität eines SWT-Steuerelements zu ergänzen, wobei der Zugriff auf das zu Grunde liegende Steuerelement weiterhin möglich ist. Mit der API für DecoratedField können Sie Dekorationen neben einem Feld hinzufügen, ausblenden und einblenden. Der Zugriff auf das zu Grunde liegende Steuerelement ist möglich, damit Sie dieses Steuerelement mit der vorhandenen SWT-API bearbeiten können, indem Sie beispielsweise seinen Inhalt, seine Farbe oder seine Schriftart festlegen.

Mit Dekoratoren versehenes Feld erstellen

Rein äußerlich verhält sich ein mit Dekoratoren versehenes Feld wie ein Steuerelement. Intern verwenden mit Dekoratoren versehene Felder ein Steuerelement für ein kombiniertes Anzeigenobjekt, um das Layout des Feldes und seiner Dekorationen zu verwalten. Dies sollte für die Clientanwendung in den meisten Fällen nicht von Belang sein, bedeutet jedoch, dass das mit Dekoratoren versehene Feld die eigentliche Erstellung des Steuerelements ausführen muss. Im folgenden Ausschnitt erstellt beispielsweise eine Anwendung in einem ihrer Dialoge ein Steuerelement für Text:

...
// Create a text field
Text text = new Text(parent, SWT.BORDER);
text.setText("irgendein Text"); 
...

Um dieses Feld mit Dekoratoren zu versehen, würde das Feld folgendermaßen erstellt werden:

...
// Create a decorated field for a text control
DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("irgendein Text");
...

Dieselben Bit für das übergeordnete Element und die Darstellung, die zur Erstellung des Basissteuerelements verwendet werden, werden auch zur Erstellung eines mit Dekoratoren versehenen Feldes verwendet. Der Hauptunterschied im Code besteht darin, dass ein Exemplar von IControlCreator bereitgestellt wird, das den speziellen, für das Feld gewünschten Steuerelementtyp erstellt. Bei Textfeldern können Sie die Klasse TextControlCreator verwenden, um die Steuerung zu erstellen. Sie haben jedoch die Möglichkeit, die Schnittstelle IControlCreator zu implementieren, um im Feld einen weiteren Steuerelementtyp (z. B. ein kombiniertes Feld oder ein Drehfeld) zu erstellen.

Dekorationen verwenden

Nachdem Sie ein mit Dekoratoren versehenes Feld erstellt haben, können Sie an einer von vier Positionen Dekorationen zu diesem Feld hinzufügen. Mit SWT-Positionskonstanten geben Sie an, wo die Dekoration platziert werden soll. Um eine Dekoration hinzuzufügen, müssen Sie ein Objekt FieldDecoration angeben, das das Image für die Dekoration und (optional) beschreibenden Text definiert, der angezeigt wird, wenn der Benutzer den Mauszeiger auf die Dekoration stellt.

...
// Create a field decoration and add it to the field
Image image = JFaceResources.getImage("myplugin.specialimage");
FieldDecoration mySpecialDecoration = new FieldDecoration(image, "Dies ist ein besonderes Feld");
field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false);
...

Mit dem Booleschen Parameter wird angegeben, ob die Dekoration nur dann angezeigt werden soll, wenn das Steuerelement fokussiert ist, oder ob sie immer angezeigt werden soll. Im Beispielfall wird die Dekoration immer angezeigt. Es kann jedoch Situationen geben, in denen die Dekoration ausgeblendet sein soll. Der folgende Ausschnitt verdeckt eine bereits erstellte Dekoration.

...
// Something has occurred that makes me want to hide the decoration
field.hideDecoration(mySpecialDecoration);
...

Falls das Image oder die Beschreibung für eine Dekoration aktualisiert wird, sollte das Feld hiervon benachrichtigt werden, damit die Dekoration erneut gezeichnet werden kann.

...
// Something has made the field extra special
mySpecialDecoration.setDescription("Dies ist ein ganz besonderes Feld");
field.updateDecoration(mySpecialDecoration);
...

Layout von mit Dekoratoren versehenen Feldern und Feldern ohne Dekoratoren erstellen

Wenn Sie ein mit Dekoratoren versehenes Feld in einem Dialog oder Fenster platzieren, sollten Sie das Layoutsteuerelement des Feldes anstelle des zu Grunde liegenden einfachen Steuerelements anordnen. Als Beispiel wird noch einmal der Code zur Erstellung eines Steuerelements für Text verwendet. Beim Anordnen eines Steuerelements für Text legt die Anwendung Layoutdaten für das Steuerelement fest.

...
// Create a text field
Text text = new Text(parent, SWT.BORDER);
text.setText("irgendein Text");
// Set the layout data
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT);
text.setLayoutData(data); 
...

Beim Layout eines mit Dekoratoren versehenen Feldes sollte die Anwendung die Layoutdaten auf dem Layoutsteuerelement des Feldes belassen. Abhängig vom gewünschten Layout muss die Größe des Feldes möglicherweise an die Größe der Dekoration angepasst werden.

...
// Create a decorated field for a text control
DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator());
Text text = (Text)field.getControl();
text.setText("irgendein Text");
// Set the layout data
GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH + 
   FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT);
field.getLayoutControl().setLayoutData(data); 
...

Die Feldunterstützung setzt in keinem Fall voraus, dass Sie in einem bestimmten Fenster oder Dialog ausschließlich mit Dekoratoren versehene Felder verwenden. Das Layout des Fensters wird jedoch möglicherweise etwas komplexer, wenn mit Dekoratoren versehene Felder mit einfachen Steuerelementen kombiniert werden. Bei der Ausrichtung von mit Dekoratoren versehenen Feldern und Feldern ohne Dekoratoren müssen Sie die Einrückung berücksichtigen, die durch die Breite der Dekoration entsteht. Die Breite einer Dekoration ist einfach die Breite ihres Images. Bei Verwendung von Dekorationen mit unterschiedlicher Breite kann dies jedoch etwas komplizierter sein. In diesem Fall können Sie eine Vereinfachung erzielen, indem Sie alle Dekorationen in FieldDecorationRegistry registrieren.

Registrierung für Felddekorationen

In der Registrierung für Felddekorationen können Sie Ihre Felddekorationen mit einer Zeichenfolgen-ID registrieren und auf sie zugreifen. Auf diese Weise können Sie bequem auf Dekorationen verweisen, die in der gesamten Anwendung verwendet werden. Wenn Sie Ihre Dekorationen anderen Plug-ins zur Verfügung stellen wollen, ist es unter Umständen sinnvoll, eine API zu definieren, die die Dekorationen zugänglich macht. Bitte beachten Sie, dass die Registrierung einer Dekoration den Lebenszyklus der Images innerhalb dieser Dekorationen nicht verwaltet. Ihre Anwendung kann bestimmen, wie diese Images verwaltet werden sollen. So könnte der Lebenszyklus eines Images beispielsweise mit der JFace-Imageregistrierung registriert und verwaltet werden. Alternativ kann die Anwendung das Image auch bei Bedarf erstellen und es anschließend verwerfen, wenn es nicht mehr benötigt wird. Das Javadoc für die Registrierungsmethoden in den Angaben zu FieldDecorationRegistry erläutert die unterschiedlichen Wege für die Angabe von Images beim Registrieren einer Dekoration.

Die Registrierung der Dekorationen in der Registrierung für Felddekorationen kann auch den Layoutprozess vereinfachen, wenn mit Dekoratoren versehene Felder und Felder ohne Dekoratoren kombiniert werden. Ein mit Dekoratoren versehenes Feld fragt standardmäßig die Registrierung für Felddekorationen ab, um die maximale Breite einer Dekoration zu ermitteln und sicherzustellen, dass alle Dekorationen diese Breite verwenden. Dies bedeutet, dass alle mit Dekoratoren versehenen Felder unabhängig von der Breite einer bestimmten Dekoration korrekt ausgerichtet werden. Um Felder ohne Dekoratoren auszurichten, können Sie mit dem Protokoll FieldDecorationRegistry auf die Breite der größten Dekoration zugreifen und die erforderliche Einrückung erstellen.

...
// Create a text field
Text text = new Text(parent, SWT.BORDER);
text.setText("irgendein Text");
// Set the layout data
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
text.setLayoutData(data); 
...

Auch wenn die Feldunterstützung keine Verwendungsart für Dekorationen vorgibt, sollte die Registrierung außerdem Standarddekorationen definieren, die von Anwendungen eingesetzt werden können, um bestimmte Statuswerte für ein Feld darzustellen. Der folgende Ausschnitt verwendet beispielsweise eine Standarddekoration für erforderliche Felder:

...
// 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);
...

Inhaltsvorschläge

Neben der Ergänzung von Feldern durch Dekorationen können Anwendungen einen Assistenten für Inhaltsvorschläge bereitstellen, der ein Dialogfenster mit Vorschlägen für ein Feld aktiviert. Um dieses Verhalten zu erreichen, können Sie einen Adapter des Typs ContentProposalAdapter für ein beliebiges Steuerelement installieren. Der folgende Ausschnitt installiert einen Adapter für Inhaltsvorschläge für ein Textsteuerelement. Dieses Textsteuerelement kann entweder direkt durch die Anwendung erstellt oder aus einem mit Dekoratoren versehenen Feld abgerufen worden sein.

...
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);

Um den Inhalt des Steuerelements abzurufen und festzulegen, sobald der Benutzer einen Vorschlag im Dialogfenster auswählt, muss der Adapter ein Exemplar von IControlContentAdapter bereitstellen, das den Inhalt eines bestimmten Steuerelementtyps abrufen und festlegen kann. Bei Textfeldern können Sie die Klasse TextContentAdapter verwenden. Sie haben jedoch auch die Möglichkeit, die Schnittstelle IControlContentAdapter zu implementieren, um den Adapter für Inhaltsvorschläge mit einem anderen Steuerelementtyp zu verwenden.

Bei der Erstellung eines Adapters für Inhaltsvorschläge müssen Sie außerdem ein Exemplar von IContentProposalProvider angeben, aus dem die eigentlichen Vorschläge abgerufen werden. Dieser Provider ist dafür zuständig, einen Bereich von Inhaltsvorschlägen zurückzugeben. Die Vorschläge selbst werden als Exemplare von IContentProposal angegeben. Hieraus können - neben anderen Informationen wie einer ausführlichen Beschreibung des Vorschlags - die Bezeichnung und der Inhalt des Vorschlags abgerufen werden.

Im obigen Beispiel wird SimpleContentProposalProvider verwendet. Dieser Provider wird durch die Angabe eines einfachen Bereichs von Zeichenfolgen als Inhaltsvorschläge definiert. Der einfache Provider implementiert das erforderliche Protokoll, um jede Zeichenfolge der erwarteten Schnittstelle IContentProposal zuzuordnen. Dank der Flexibilität von IContentProposalProvider können Sie einen Vorschlagsprovider mit erweiterten Funktionen implementieren. Denkbar wäre in diesem Zusammenhang die Filterung der Vorschläge basierend auf dem Inhalt des Steuerelements, die Bereitstellung erläuternder Bezeichnungen im Dialogfenster anstelle des tatsächlich eingefügten Inhalts und die Angabe der erwarteten Cursorposition nach dem Einfügen eines Vorschlags. Im Beispiel für die Feldunterstützung können Sie Implementierungselemente von IContentProposalProvider für einen erweiterten Einsatz anzeigen und suchen.

Adapter für Inhaltsvorschläge konfigurieren

Sie wissen bereits, dass die Basisdefinition eines Adapters für Inhaltsvorschläge das Steuerelement enthält, für das die Vorschläge bereitgestellt werden. Außerdem enthalten sind der Inhaltsadapter, mit dem der Inhalt des Steuerelements geändert wird, und der Vorschlagsprovider, der die Liste der Vorschläge im Dialogfenster definiert. Neben diesen Grundlagen gibt es viele Möglichkeiten für die Konfiguration des Adapters für Inhaltsvorschläge:

Im Beispiel für die Feldunterstützung können Sie diese verschiedenen Optionen in den Benutzervorgaben für das Beispiel konfigurieren und mit verschiedenen Kombinationen experimentieren. Der Adapter kann beispielsweise so konfiguriert werden, dass er mit einer Tastenkombination explizit aufgerufen wird und den Inhaltsvorschlag in das Steuerelement einfügt und sich somit ganz ähnlich wie die Unterstützung für Inhalt in einem Texteditor verhält. Alternativ können Sie ihn ohne explizite Tastenanschläge, Zeichen für die automatische Aktivierung und Inhaltsersetzung konfigurieren. Dann verhält sich der Adapter eher wie die Fertigstellung bei laufender Eingabe, die in URL- oder Suchfeldern von Web-Browsern verwendet wird. Speziellere Angaben über diese Methoden und ihre Interaktion untereinander finden Sie im Javadoc.

Feldunterstützung der Workbench

Durch die Feldunterstützung auf JFace-Ebene ist Ihre Anwendung sehr flexibel, wenn es darum geht, Felder mit Dekoratoren zu versehen und Vorschläge für den Feldinhalt anzuzeigen. Dies ist bei eigenständigen JFace-Anwendungen oder Rich Client-Anwendungen sinnvoll und wünschenswert. Falls Sie jedoch beabsichtigen, Ihre Anwendung in andere Plug-ins wie Eclipse SDK oder in Plug-ins anderer Anbieter zu integrieren, ist es wahrscheinlich sinnvoll, die Feldunterstützung so einzusetzen, dass sie mit anderen Plug-ins konsistent ist. Die Workbench definiert Dienstprogrammklassen, die die Feldunterstützung für bestimmte Arten von Interaktionen einsetzen.

Die Klasse ContentAssistField beispielsweise erstellt ein Feld, das ein Glühbirnensymbol enthält, um den Benutzer auf die Verfügbarkeit der Unterstützung für Inhalt hinzuweisen. Außerdem konfiguriert sie einen Adapter für Inhaltsvorschläge, damit ähnlich wie bei der Unterstützung für Inhalt Einfügungen erfolgen können. Schließlich stellt sie einen Handler für den Befehl der Unterstützung für Inhalt auf Workbenchebene bereit, damit das Dialogfenster mit dem Inhaltsvorschlag geöffnet wird, wenn der Benutzer den Tastenanschlag oder die Auslöserfolge aufruft, der/die in den Tastenbelegungen der Workbench angegeben ist. Weitere Details über diese Dienstprogrammklassen können Sie in den Angaben zum Paket org.eclipse.ui.fieldassist nachlesen.

Dieses Paket wird voraussichtlich erweitert, wenn die Workbench den Einsatz der Feldunterstützung ausdehnt und die Verwendung von Dekorationen für bestimmte Feldstatuswerte standardisiert.