TreeTableView mit editierbaren Feldern
Hier ist eine kleine beispielhafte Minianwendung mit einem editierbarem TreeTableView:
package com.sowas.javawiki.treetableview; import javafx.application.Application; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableColumn.CellDataFeatures; import javafx.scene.control.TreeTableView; import javafx.scene.control.cell.TextFieldTreeTableCell; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.util.Callback; import javafx.util.converter.NumberStringConverter; import java.util.ArrayList; import java.util.List; public class TreeTableViewDemo extends Application { @Override public void start(Stage primaryStage) { final ObservableList<Data> allData = FXCollections.observableArrayList(); ObservableList<String> numberStrings = FXCollections.observableArrayList("Eins", "Zwei", "Drei", "Vier"); for (int i = 0; i < 3; i++) { allData.add(new Data("Knoten " + i, FXCollections.observableArrayList(new Dataset(numberStrings.get(0), 1), new Dataset(numberStrings.get(1), 2), new Dataset(numberStrings.get(2), 3), new Dataset(numberStrings.get(3), 4)))); } final TreeTableView<Dataset> treeTableView = new TreeTableView<>(new TreeItem<Dataset>(new Dataset("", 0))); treeTableView.setShowRoot(false); for (Data data : allData) { TreeItem<Dataset> ti = new TreeItem<>(new Dataset(data.getName(), null)); ti.setExpanded(true); treeTableView.getRoot().getChildren().add(ti); for (Dataset dataset : data.getData()) { TreeItem treeItem = new TreeItem(dataset); ti.getChildren().add(treeItem); } } TreeTableColumn<Dataset, String> clientCol = new TreeTableColumn<>("Knoten"); clientCol.setCellValueFactory((param) -> { return param.getValue().isLeaf() ? new SimpleStringProperty("") : param.getValue().getValue().strProperty(); }); clientCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); clientCol.setOnEditCommit((evt) -> { if (evt.getRowValue().isLeaf()) { return; } for (Data data : allData) { if (data.getName().equals(evt.getOldValue())) { data.setName(evt.getNewValue()); } } evt.getRowValue().getValue().setStr(evt.getNewValue()); }); TreeTableColumn<Dataset, String> titleCol = new TreeTableColumn<>("Zahl"); titleCol.setCellValueFactory(new Callback<CellDataFeatures<Dataset, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(CellDataFeatures<Dataset, String> param) { return param.getValue().isLeaf() ? param.getValue().getValue().strProperty() : new SimpleStringProperty(""); } }); titleCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); titleCol.setOnEditCommit((evt) -> { final String ov = evt.getOldValue(); final String nv = evt.getNewValue(); for (Data data : allData) { for (Dataset dataset : data.getData()) { if (ov.equals(dataset.getStr())) { dataset.setStr(nv); } } } numberStrings.set(numberStrings.indexOf(ov), nv); }); TreeTableColumn<Dataset, Number> valueCol = new TreeTableColumn<>("Wert"); valueCol.setCellValueFactory(new Callback<CellDataFeatures<Dataset, Number>, ObservableValue<Number>>() { @Override public ObservableValue<Number> call(CellDataFeatures<Dataset, Number> param) { return param.getValue().getValue().noProperty(); } }); valueCol.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn(new NumberStringConverter())); valueCol.setOnEditCommit((evt) -> { evt.getRowValue().getValue().setNo(evt.getNewValue()); }); treeTableView.getColumns().addAll(clientCol, titleCol, valueCol); treeTableView.setColumnResizePolicy(TreeTableView.CONSTRAINED_RESIZE_POLICY); treeTableView.getSelectionModel().setCellSelectionEnabled(true); treeTableView.setEditable(true); final VBox vBox = new VBox(treeTableView); final Scene scene = new Scene(vBox); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } class Data { private String name; private List<Dataset> data = new ArrayList<>(); public Data(String name, ObservableList<Dataset> data) { this.name = name; this.data = data; } public List<Dataset> getData() { return data; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class Dataset { StringProperty str = new SimpleStringProperty(); ObjectProperty<Number> no = new SimpleObjectProperty<>(); public Dataset(String s, Number n) { str.set(s); no.set(n); } public Number getNo() { return no.get(); } public ObjectProperty<Number> noProperty() { return no; } public void setNo(Number no) { this.no.set(no); } public String getStr() { return str.get(); } public StringProperty strProperty() { return str; } public void setStr(String str) { this.str.set(str); } }
Stichworte:
JavaFX TreeTableView, editierbar, Beispielanwendung, Example