Jetzt anmelden...

Login
Passwort
Registrieren
28.09.21 841 Views Kommentare [0] 0 0

credit: ©arthead/ adobe

JAVA Tutorial #57

JavaFX TableView

Die TableView ermöglicht es dir, Objektdaten in Form einer Tabelle in deiner JavaFX-Anwendung darzustellen. Die TableView gehört zu den eher komplexeren JavaFX-Nodes - doch keine Sorge: Am Ende des Tutorials gehört Sie dir!

Falconbyte unterstüzen

Betrieb und Pflege von Falconbyte brauchen viel Zeit und Geld. Um dir auch weiterhin hochwertigen Content anbieten zu können, kannst du uns sehr gerne mit einem kleinen "Trinkgeld" unterstützen.

Schnelles Code-Beispiel

// TableView-Instanz
TableView<Produkt> tabelle = new TableView<>();

// Spalten erstellen (hier nur eine Spalte)
TableColumn<TypTabelle, TypSpalte> columnX = new TableColumn<>("Spaltenname");
columnX.setCellValueFactory(new PropertyValueFactory<>("instanzvariable"));

// Spalten in Tabelle packen
tabelle.getColumns().addAll(columnX);

// Objekte aus einer ObservableList in die Tabelle laden
tabelle.setItems(getListe());
    

Was ist eine TableView?

Eine TableView macht es dir möglich, eine Tabellen-Ansicht mit Objektdaten darzustellen. Repräsentiert ist die TableView in der JavaFX-Klasse javafx.scene.control.TableView. Wie bei der ListView steht hinter der TableView eine ObservableList, welche die einzelnen Elemente verwaltet (dazu weiter unten mehr).

Hier ein Beispiel, wie das dann in einer JavaFX-Anwendung aussehen kann:

Java JavaFX TableView

In diesem Ausschnitt werden verschiedene Eigenschaften von drei Objekten des Typs Produkt in Tabellenform angezeigt.

Die TableView ist eine generische Klasse, das heißt, dass wir bei der Erstellen einen Typ-Parameter in spitzen Klammern angeben müssen. Dieser Typ-Parameter bestimmt, welche Objekt-Typen die Tabelle aufnehmen soll.

Wenn wir zum Beispiel wie im Screenshot oben Daten von Objekten des Typs Produkt in der Tabelle angezeigt haben wollen, dann sieht die Erzeugung eines TableView-Objekts so aus:

TableView<Produkt> tabelle = new TableView<>();

Die Beispielklasse: Produkt

Wie gesagt sind es die Daten (genauer gesagt: Werte der Instanzvariablen) von Produkt-Objekten, die in die Tabelle kommen. Die Implementierung der Klasse Produkt ist deshalb sehr relevant und es müssen vor allem die Getter-Methoden nach der konventionellen Schreibweise gesetzt sein, damit die Objektdaten in die Tabelle übertragen werden können:

public class Produkt {

    int nummer;
    String name;
    double preis;


    public Produkt(int nummer, String name, double preis) {
        this.nummer = nummer;
        this.name = name;
        this.preis = preis;
    }

    public int getNummer() {
        return nummer;
    }

    public String getName() {
        return name;
    }

    public double getPreis() {
        return preis;
    }

    // Setter hier aus Platzgründen ausgelassen

}
 

Aufbau einer TableView

Mit dem Erzeugen eines TableView-Objekts ist es noch nicht getan. Die Tabelle muss im nächsten Schritt nämlich noch mit den einzelnen Spalten strukturell aufgebaut werden.

TableColumn

Eine Spalte wird durch die Klasse TableColumn repräsentiert. TableColumn ist gleich doppelt generisch und verlangt bei der Initialisierung zusätzlich noch ein String-Argument. Hier ein allgemeines Beispiel:

JavaFX TableView

Willkommen beim Parameter-Overlord 😅! Jetzt etwas genauer:

  • Der erste generische Typ-Parameter verlangt den grundätzlichen Typ der Objekte, die in die TableView aufgenommen werden sollen.
  • Der zweite generische Typ-Parameter verlangt den Objekttyp für diese Spalte.
  • Der "normale" Parameter in den runden Klammern nimmt immer einen String auf. Dieser Wert legt fest, wie der Spaltenkopf in der Tabelle heißen soll.

Konkret sieht das für unseren Spalten der Tabelle so aus:

TableColumn<Produkt, Integer> nummer_column = new TableColumn<>("Nummer");
TableColumn<Produkt, String> name_column = new TableColumn<>("Name");
TableColumn<Produkt, Double> preis_column = new TableColumn<>("Preis");

setCellValueFactory()

Jetzt müssen wir noch dafür sorgen, dass die Werte der Instanzvariablen der Produkt-Objekte auch tatsächlich in den Zellen der entsprechenden Spalte landen.

Hierzu rufen wir auf der TableColumn-Referenz die Methode setCellValueFactory() auf und setzen als Argument ein neues PropertyValueFactory-Objekt ein.

Das PropertyValueFactory-Objekt stellt die direkte Verbindung zur Instanzvariable des Produkt-Objekts her und liest deren aktuellen Wert aus:

nummer_column.setCellValueFactory(new PropertyValueFactory<>("nummer"));
name_column.setCellValueFactory(new PropertyValueFactory<>("name"));
preis_column.setCellValueFactory(new PropertyValueFactory<>("preis"));

Damit das auch funktioniert, müssen wir auf zwei Dinge achten:

  • Der Parameter-Wert in den runden Klammern muss exakt so heißen wie die entsprechende Instanzvariable der Klasse Produkt.
  • In der Klasse Produkt muss es eine konventionelle getter-Methode für die jeweilige Instanzvariable geben (siehe oben).

Spalten der Tabelle hinzufügen

Schließlich müssen die einzelnen Spalten noch der TableView hinzugefügt werden. Das läuft über den verketteten Methodenaufruf getColumns().addAll():

tabelle.getColumns().addAll(nummer_column, name_column, preis_column);

Unsere TableView ist nun fertig strukturiert und sieht so aus:

Java JavaFX TableView leer

Daten einlesen

Unsere Tabelle ist jetzt noch leer und was jetzt noch fehlt, sind die Daten aus den Produkt-Objekten.

Hierzu muss man wissen, dass die einzelnen Elemente nicht in der TableView selbst gespeichert werden. Stattdessen ist in der TableView eine ObservableList verbaut, die für die eigentliche Verwaltung der einzelnen Elemente zuständig ist.

Wie gehen wir also vor?

Zunächst schreiben wir eine Methode, welche eine mit Produkt-Objekten gefüllte ObservableList zurückliefert:

public ObservableList<Produkt> getProdukte(){
    ObservableList<Produkt> liste = FXCollections.observableArrayList();
    liste.add(new Produkt(1, "Tablet", 500));
    liste.add(new Produkt(2, "Notebook", 1000));
    liste.add(new Produkt(3, "Smartphone", 900));
    return liste;
}                

Schließlich verbauen wir die die ObservableList in der Tabelle, indem wir auf der TableView-Referenz die Methode setItems() aufrufen:

tabelle.setItems(getProdukte());                

Schon sind wir fertig:

Java JavaFX TableView

Vollständiger Code

Für alle mit wenig Zeit - hier der vollständige Code:

package p1;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage){

        TableView<Produkt> tabelle = new TableView<>();

        // Nummer-Spalte
        TableColumn<Produkt, Integer> nummer_column
        = new TableColumn<>("Nummer");
        nummer_column.setCellValueFactory(new PropertyValueFactory<>("nummer"));
        nummer_column.setMinWidth(200);

        // Name-Spalte
        TableColumn<Produkt, String> name_column = new TableColumn<>("Name");
        name_column.setCellValueFactory(new PropertyValueFactory<>("name"));
        name_column.setMinWidth(200);

        // Preis-Spalte
        TableColumn<Produkt, Double> preis_column = new TableColumn<>("Preis");
        preis_column.setCellValueFactory(new PropertyValueFactory<>("preis"));
        preis_column.setMinWidth(200);

        //Spalten in Tabelle packen:
        tabelle.getColumns().addAll(nummer_column, name_column, preis_column);

        //Daten in die Tabelle laden:
        tabelle.setItems(getProdukte());

        HBox box = new HBox();
        box.getChildren().add(tabelle);

        primaryStage.setScene(new Scene(box, 640, 480));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
    public ObservableList<Produkt> getProdukte(){
        ObservableList<Produkt> liste = FXCollections.observableArrayList();
        liste.add(new Produkt(1, "Tablet", 500));
        liste.add(new Produkt(2, "Notebook", 1000));
        liste.add(new Produkt(3, "Smartphone", 900));
        return liste;
    }

}

Falconbyte unterstützen

Kommentar schreiben

Alle Kommentare

Es gibt bislang noch keine Kommentare zu diesem Thema.

Die Klasse Object

Erfahren Sie alles über die Mutter aller Klassen

switch/ case Anweisung

Benötigen wir eine Unterscheidung nach vielen Fällen empfehlen sich switch-case-Statements.

Statische Elemente

Statische Variablen und Methoden nutzen

FALCONBYTE.NET

Handmade with 🖤️

© 2018-2021 Stefan E. Heller

Impressum | Datenschutz

Falconbyte GitHub facebook programmieren lernen twitter programmieren lernen discord programmieren lernen