Java FX TableView |
TableView<Spieler> table = new TableView<Spieler>(); ObservableList<Spieler> data = FXCollections.observableArrayList( new Spieler("Batman", 0), new Spieler("Superman", 0), new Spieler("Spiderman", 0), new Spieler("Gaston", 100), new Spieler("Goofy", 0)); table.setItems(data);Die Highscore-Tabelle besteht aus zwei Spalten, dem Spielernamen und der Punktzahl. Eine Spalte wird durch die Klasse TableColumn realisiert. Die Spalten erhalten als Generics einmal die Klasse Spieler, aber zusätzllich den Typ der aufgezeichneten Spalte. Beim Namen ist dies String, bei den Punkten ist das Integer, weil int in den Generics nichts verloren hat.
TableColumn<Spieler, String> spalteName = new TableColumn<Spieler, String>("Name"); spalteName.setMinWidth(100); // Mindestbreite setzen spalteName.setCellValueFactory( new PropertyValueFactory<Spieler, String>("name")); // Die Spalte wird in die Tabelle gehängt. table.getColumns().add(spalteName);Mit der CellValueFactory wird dafür gesorgt, dass der Inhalt der Spalte auch dargestellt wird. Der Parameter des Konstruktors der Klasse PropertyValueFactory muss mit dem Namen der Getter-Methode übereinstimmen. Bei name muss es also eine Methode getName zum Ermittel des Spalteninhalts geben.
Schließlich muss natürlich irgendwann die Spalte in die Tabelle eingefügt werden.
Comparator<Spieler> scoreVergleicher = new Comparator<Spieler>() { public int compare(Spieler orig, Spieler vgl) { int oPkte = orig.getPunkte(); int vPkte = vgl.getPunkte(); if (oPkte < vPkte) return 1; if (oPkte > vPkte) return -1; return 0; } }; // Nun kann sort mit scoreVergleicher aufgerufen werden: data.sort(scoreVergleicher);Änderungen an der ObservableList schlagen sich sofort auf die TableView durch, weil die List das Datenmodell für die TableView darstellt.
spalteName.setCellFactory(TextFieldTableCell.forTableColumn()); spalteName.setOnEditCommit( new EventHandler<CellEditEvent<Spieler, String>>() { @Override public void handle(CellEditEvent<Spieler, String> t) { ((Spieler) t.getTableView().getItems().get( t.getTablePosition().getRow()) ).setName(t.getNewValue()); } } ); // Die Tabelle muss zum Editieren freigeschaltet werden. table.setEditable(true);Etwas anders läuft es, wenn Sie die Punkte ändern wollen. Das war ein besonderer Wunsch von Batman. Ich kann mir allerdings nicht vorstellen, dass Batman schummeln wollte.
spaltePunkte.setCellFactory(TextFieldTableCell.<Spieler, Integer> forTableColumn(new IntegerStringConverter())); spaltePunkte.setOnEditCommit( new EventHandler<CellEditEvent<Spieler, Integer> >() { @Override public void handle(CellEditEvent<Spieler, Integer> evt) { Integer neuWert = evt.getNewValue(); evt.getTableView().getItems().get( evt.getTablePosition().getRow()) .setPunkte(neuWert); // Punktzahl wurde geändert: neu sortieren! data.sort(scoreVergleicher); } } );
import java.util.Comparator; import javafx.application.Application; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn.CellDataFeatures; import javafx.scene.control.TableColumn.CellEditEvent; import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.scene.layout.FlowPane; import javafx.scene.layout.HBox; import javafx.stage.Stage; import javafx.util.Callback; import javafx.util.converter.IntegerStringConverter; public class FxTable extends Application { @Override public void start(Stage stage) { TableView<Spieler> table = new TableView<Spieler>(); ObservableList<Spieler> data = FXCollections.observableArrayList( new Spieler("Badman", 120), new Spieler("Sabberman", 80), new Spieler("Spinnerman", 0), new Spieler("Captain Alergica", 100), new Spieler("Booman", 0)); table.setItems(data); table.setEditable(true); TableColumn<Spieler, String> spalteName = new TableColumn<Spieler, String>("Name"); spalteName.setMinWidth(100); // Der String im Konstruktor von PropertyValueFactory // muss mit der get-Methode von Spieler korrespondieren spalteName.setCellValueFactory( new PropertyValueFactory<Spieler, String>("name")); spalteName.setCellFactory(TextFieldTableCell.forTableColumn()); // Spalte soll änderbar sein spalteName.setOnEditCommit( new EventHandler<CellEditEvent<Spieler, String>>() { @Override public void handle(CellEditEvent<Spieler, String> t) { ((Spieler) t.getTableView().getItems().get( t.getTablePosition().getRow()) ).setName(t.getNewValue()); } } ); // Sortieren nach der Highscoreliste Comparator<Spieler> scoreVergleicher = new Comparator<Spieler>() { public int compare(Spieler orig, Spieler vgl) { int oPkte = orig.getPunkte(); int vPkte = vgl.getPunkte(); if (oPkte < vPkte) return 1; if (oPkte > vPkte) return -1; return 0; } }; data.sort(scoreVergleicher); TableColumn<Spieler, Integer> spaltePunkte = new TableColumn<>("Punkte"); spaltePunkte.setMinWidth(100); spaltePunkte.setCellValueFactory( new Callback<CellDataFeatures<Spieler, Integer>, ObservableValue<Integer>>() { @Override public ObservableValue<Integer> call( CellDataFeatures<Spieler, Integer> c) { return new SimpleIntegerProperty(c.getValue(). getPunkte()).asObject(); } }); spaltePunkte.setCellFactory( TextFieldTableCell.<Spieler, Integer>forTableColumn( new IntegerStringConverter())); spaltePunkte.setOnEditCommit( new EventHandler<CellEditEvent<Spieler, Integer> >() { @Override public void handle(CellEditEvent<Spieler, Integer> evt) { Integer neuWert = evt.getNewValue(); evt.getTableView().getItems().get( evt.getTablePosition().getRow()) .setPunkte(neuWert); // Punktzahl wurde geändert: neu sortieren! data.sort(scoreVergleicher); } } ); table.getColumns().add(spalteName); table.getColumns().add(spaltePunkte); Scene scene = new Scene(table); stage.setScene(scene); stage.show(); stage.setWidth(450); stage.setHeight(550); } public static void main(String[] args) { launch(args); } }
Homepage - Java - Java FX | (C) Copyright 2017 Arnold Willemer |