Training „git“
07.10.2010 - 08.10.2010, Essen
Training „Eclipse RCP“
28.03.2011 - 01.04.2011, Dortmund
Eclipse RCP

JFace Überblick, JFace Structured Viewers

JFace

SWT beschränkt sich auf die Bereitstellung eines APIs für die zugrundeliegenden GUI-Bibliotheken, weitergehende Komponenten werden in JFace bereitgestellt. Hier finden sich u.a.:

JFace Structured Viewer

JFace Structured Viewer stellen eine Abstraktion bereit, die Inhalte aus beliebigen Java-Datenstrukturen in einem Widget zur Anzeige bringt. Folgende Viewer stehen zur Verfügung:

JFace Combo-/ListViewer

Ein JFace ComboViewer ist ein JFace Structured Viewer. Er ist für die Verwaltung der Inhalte eines SWT Combo-Controls zuständig (analog JFace ListViewer):

JFace Viewer I

Einen ComboViewer kann zu einem bereits vorhandenen Combo-Control erzeugt werden:

ComboViewer comboViewer = new ComboViewer(someCombo);

Alternativ kann man dem Viewer die Erzeugung des Controls überlassen:

ComboViewer comboViewer = new ComboViewer(parentComposite, SWT.READ_ONLY);
Combo combo = comboViewer.getCombo();

Ein Viewer wird mit einem ContentProvider, LabelProvider und Input-Objekt versehen. Diese Objekte beschreiben die anzuzeigenden Daten:

Input-Objekt

Das Input-Objekt repräsentiert die anzuzeigenden Inhalte. Es kann sich um ein beliebiges Java-Objekt handeln:

comboViewer.setInput("1 2 3");

ContentProvider

Woher weiß der ComboViewer, wie mit diesem Eingabe-Objekt umzugehen ist? Dazu wird dem ComboViewer ein ContentProvider gesetzt. Der ContentProvider ist dafür zuständig, die Eingabedaten in eine dem Viewer verständliche Struktur zu bringen. Dazu muss er das Eingabeobjekt in ein Array von Zeilenobjekten konvertieren:

// Input object will be a String in this example, so we need to split the String
comboViewer.setContentProvider(new IStructuredContentProvider() {

    public Object[] getElements(Object inputElement) {
        return ((String) inputElement).split(" ");
    }

    /* ... */

});
comboViewer.setInput("1 2 3"); 

Bei diesen Zeilenobjekten kann es sich um beliebige Java-Objekte handeln. Jedes Zeilenobjekt im zurückgegebenem Array wird zu einer Auswahloption in der Combo-Box.

Liegt das Input-Objekt bereits als Java-Array oder Java-Collection vor, muss man den ContentProvider nicht selbst implementieren, sondern kann einen ArrayContentProvider verwenden:

// Input object will be a Collection here, so we use ArrayContentProvider
comboViewer.setContentProvider(ArrayContentProvider.getInstance());
comboViewer.setInput(someCollection);

LabelProvider

Der LabelProvider ist dafür zuständig, zu einem Zeilenobjekt die zur Anzeige benötigten Informationen wie Label oder Bild zu liefern:

comboViewer.setContentProvider(ArrayContentProvider.getInstance());
comboViewer.setLabelProvider(new LabelProvider() {
        
    @Override
    public String getText(Object element) {
        SomeObject element = (SomeObject) element;
        return element.getName();
    }

});
comboViewer.setInput(someCollection);

Der setInput-Aufruf sollte immer zuletzt erfolgen, da es die Befüllung der Combo-Box auslöst. Zu diesem Zeitpunkt muss bereits ein Content- und LabelProvider gesetzt sein.

Selektion

An die aktuelle Selektion eines JFace-Viewers gelangen Sie über getSelection():

ISelection selection = someViewer.getSelection();

Das zurückgegebene Interface ISelection ist ein sehr allgemeines Interface. Selektionen, die Elemente beinhalten, werden als IStructuredSelection abgebildet. Alle StructuredViewer geben eine IStructuredSelection zurück. Mittels der IStructuredSelection können Sie das erste selektierte Element abfragen oder über alle selektierten Elemente iterieren:

IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (!structuredSelection.isEmpty()) {
    // get first element ...
    Object firstElement = structuredSelection.getFirstElement();

    // or iterate over all elements
    for (Iterator iterator = structuredSelection.iterator(); iterator.hasNext();) {
        Object element = iterator.next();
    }
}

Sie können zudem die aktuelle Selektion mit einem ISelectionChangedListener beobachten:

someViewer.addSelectionChangedListener(new ISelectionChangedListener() {

    public void selectionChanged(SelectionChangedEvent event) {
        // Handle selection changed event here
        ISelection selection = event.getSelection();
    }
    
});
Thomas Papendieck, 18. Mai, 08:59 Uhr

Hallo,

Vielen dank für dieses sehr gute Tutorial.

Aber auf dieser Seite fehlt mir etwas die Übersicht. Der Begriff "Selection" ist für mich nicht klar zuzuorden. Während ich auf den vorhergehenden Seiten den Eindruck gewann, dass eine Selection ein Benutzeraktion ist, über deren Auftreten ich mich mit einem "SelectionListener" (als Ersatz/Erweiterung des bekannten ActionListeners) informieren lassen kann scheint es nun eine Komponente "Selection" zu geben.

Können Sie weiter vorn näher auf das Verhhältnis SelectionListener/ActionListener eingehen und hier auf das Verhältnis Selection als Aktion/Komponente?

MfG
Thomas

Ralf Ebert, 18. Mai, 18:07 Uhr

Selection meint bei JFace immer die aktuell ausgewählten Elemente. Nicht zu verwechseln mit dem Selection-Event (z.B. "auslösen" eines Buttons bei Klick) für Controls in SWT. Einen ActionListener gibt es nicht...

Über Ihre Kommentare und Hinweise freue ich mich sehr:
Ralf Ebert | Eclipse RCP Buch | JFace Überblick, JFace Structured Viewers