TableView
Das TableView
dient zur Darstellung und Editierung von Daten in tabellarischer
Form. Auch wenn möglich, sollte das TableView
nicht zum Layout von Komponenten
als Container missbraucht werden. Hier sollte lieber auf das GridPane
oder andere
Layout - Komponenten zurückgegriffen werden.
Das TableView
ist Verwandt mit dem ListView
und gehört zu den etwas
komplexeren Komponenten. Bevor das TableView
eingesetzt werden kann, sollte man
sich etwas Zeit für die Einarbeitung lassen.
Um der Thematik TableView
näher zu kommen, wollen wir als erstes Beispiel
eine sehr einfache Tabelle erzeugen, die uns in den Zellen ein paar Texte ausgibt.
Die nachfolgende Grafik zeigt, was wir als Ergebnis unserer Programmierung erhalten werden.
Bevor wir uns der TableView
-Programmierung hingeben programmieren wir die Klasse
ValueClass
(Name ist willkürlich). Diese Klasse stellt später die Daten
für die Darstellung im TableView
zur Verfügung.
public class ValueClass { private String column1; private String column2; private String column3; public ValueClass(String column1, String column2, String column3) { this.column1 = column1; this.column2 = column2; this.column3 = column3; } public String getColumn1() { return column1; } public String getColumn2() { return column2; } public String getColumn3() { return column3; } }
Nachdem wir die Datenklasse programmiert haben, wenden wir uns der Programmierung
der Darstellung des TableView
zu.
import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.Stage; public class MyTableView extends Application { public static void main(String[] args) { launch(args); } public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("MyTableView"); stage.setWidth(450); stage.setHeight(500); TableView tableView = createTableView(); ((Group) scene.getRoot()).getChildren().addAll(tableView); stage.setScene(scene); stage.show(); } private TableView createTableView() { // Darzustellende Daten ObservableList<ValueClass> data = FXCollections.observableArrayList( new ValueClass("R0 C0", "R0 C1", "R0 C2"), new ValueClass("R1 C0", "R1 C1", "R1 C2"), new ValueClass("R2 C0", "R2 C1", "R2 C2"), new ValueClass("R3 C0", "R3 C1", "R3 C2"), new ValueClass("R4 C0", "R4 C1", "R4 C2") ); // Spaltendefinition TableColumn<ValueClass, String> col1 = new TableColumn<ValueClass, String>("Col 1"); col1.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column1")); TableColumn<ValueClass, String> col2 = new TableColumn<ValueClass, String>("Col 2"); col2.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column2")); TableColumn<ValueClass, String> col3 = new TableColumn<ValueClass, String>("Col 3"); col3.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column3")); // Tabellenerzeugung TableView<ValueClass> tableView = new TableView<ValueClass>(); tableView.setItems(data); tableView.getColumns().add(col1); tableView.getColumns().add(col2); tableView.getColumns().add(col3); return tableView; } }
Die Methode start
definiert allgemein das JavaFX View und ist unabhängig vom
TableView
. Das darzustellende TableView
programmieren wir in der Methode
createTableView
. Als Erstes definieren wir mit data
ein
FXCollections.observableArrayList
, welches die darzustellenden Daten enthält.
Im Anschluss definieren wir drei Spalten, die wir dem TableView
zuweisen.
Abschließend geben wir das TableView
als Ergebnis der Methode zurück.
Im aktuellen Stand unseres TableView
werden die Daten wie gewollt dargestellt.
Was aber etwas unangenehm auffällt, ist dass unsere Tabelle eine zusätzliche, leere Spalte
und zusätzliche, leere Zeilen zeichnet. Im Nachfolgendem wollen wir unser Programm derart
modifizieren, sodass keine zusätzliche Spalte und keine zusätzliche Zeilen gezeichnet werden.
Um das zusätzliche Zeichnen der letzten Spalte zu vermeiden, setzen wir das Feld
columnResizePolicy
der TableView
von TableViewUNCONSTRAINED_RESIZE_POLICY
auf TableView.CONSTRAINED_RESIZE_POLICY
.
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
Um das Zeichnen der zusätzlichen Zeilen zu verhindern, ist ein wenig mehr Aufwand notwendig.
Hier definieren wir zwei Callback
Objekte, welche das Zeichnen der Zeilen und
der einzelnen Zellen behandeln. Das nachfolgende Beispiel zeigt die Implementierung der
beiden Callback
Objekte für unser Beispiel.
Callback<TableColumn<ValueClass,String>, TableCell<ValueClass,String>> myCallback = new Callback<TableColumn<ValueClass,String>, TableCell<ValueClass,String>>() { @Override public TableCell call(TableColumn param) { return new TableCell() { @Override protected void updateItem(Object item, boolean empty) { if (empty) super.setVisible(false); else super.setText(item.toString()); } }; } }; col1.setCellFactory(myCallback); col2.setCellFactory(myCallback); col3.setCellFactory(myCallback); Callback<TableView<ValueClass>,TableRow<ValueClass>> myCallback2 = new Callback<TableView<ValueClass>,TableRow<ValueClass>>() { @Override public TableRow call(TableView table) { return new TableRow<ValueClass>() { protected void updateItem(ValueClass item, boolean empty) { if (empty) super.setStyle("-fx-background-color: lightyellow"); super.updateItem(item,empty); } }; } }; tableView.setRowFactory(myCallback2); return tableView; }
Nachfolgend der vollständige Quelltext unserer Tabelle zur einfachen Darstellung von Daten.
import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.stage.Stage; import javafx.util.*; public class MyTableView4 extends Application { public static void main(String[] args) { launch(args); } public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("MyTableView"); stage.setWidth(450); stage.setHeight(500); TableView tableView = createTableView(); ((Group) scene.getRoot()).getChildren().addAll(tableView); stage.setScene(scene); stage.show(); } private TableView createTableView() { // Darzustellende Daten ObservableList<ValueClass> data = FXCollections.observableArrayList( new ValueClass("R0 C0", "R0 C1", "R0 C2"), new ValueClass("R1 C0", "R1 C1", "R1 C2"), new ValueClass("R2 C0", "R2 C1", "R2 C2"), new ValueClass("R3 C0", "R3 C1", "R3 C2"), new ValueClass("R4 C0", "R4 C1", "R4 C2") ); // Spaltendefinition TableColumn<ValueClass, String> col1 = new TableColumn<ValueClass, String>("Col 1"); col1.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column1")); TableColumn<ValueClass, String> col2 = new TableColumn<ValueClass, String>("Col 2"); col2.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column2")); TableColumn<ValueClass, String> col3 = new TableColumn<ValueClass, String>("Col 3"); col3.setCellValueFactory(new PropertyValueFactory<ValueClass, String>("column3")); // Tabellenerzeugung TableView<ValueClass> tableView = new TableView<ValueClass>(); tableView.setItems(data); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tableView.getColumns().add(col1); tableView.getColumns().add(col2); tableView.getColumns().add(col3); Callback<TableColumn<ValueClass,String>, TableCell<ValueClass,String>> myCallback = new Callback<TableColumn<ValueClass,String>, TableCell<ValueClass,String>>() { @Override public TableCell call(TableColumn param) { return new TableCell() { @Override protected void updateItem(Object item, boolean empty) { if (empty) super.setVisible(false); else super.setText(item.toString()); } }; } }; col1.setCellFactory(myCallback); col2.setCellFactory(myCallback); col3.setCellFactory(myCallback); Callback<TableView<ValueClass>,TableRow<ValueClass>> myCallback2 = new Callback<TableView<ValueClass>,TableRow<ValueClass>>() { @Override public TableRow call(TableView table) { return new TableRow<ValueClass>() { protected void updateItem(ValueClass item, boolean empty) { if (empty) super.setStyle("-fx-background-color: lightyellow"); super.updateItem(item,empty); } }; } }; tableView.setRowFactory(myCallback2); return tableView; } }
Die Ausführung des Programms führt zur Anzeige folgenden Fensters:
http://docs.oracle.com/
12 Table View
http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
Jonathan Giles - Tech Lead, JavaFX UI Controls
Hacking TableView
http://www.youtube.com/watch?v=udc2iRZBF0M
http://docs.oracle.com/
JavaFX 2 - TableView - API Dokumentation