Skip to content

Instantly share code, notes, and snippets.

@nezarjhons
Forked from sh9va/TreeTableView.java
Created September 15, 2020 02:35
Show Gist options
  • Save nezarjhons/6d28cbb2eaef578a94e4b07fd963b871 to your computer and use it in GitHub Desktop.
Save nezarjhons/6d28cbb2eaef578a94e4b07fd963b871 to your computer and use it in GitHub Desktop.
JavaFX TableView in TableView (JavaFx Tree like TableView)
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TreeTableView extends Application {
private TableView<Person> table = new TableView<Person>();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
constructTable();
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
private void constructTable() {
TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<Person, String>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
TableColumn<Person, String> emailCol = new TableColumn<Person, String>("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
table.setItems(getData());
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
table.setRowFactory(tv -> new TableRow<Person>() {
Node detailsPane ;
{
this.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected ) {
detailsPane = constructSubTable(getItem());
this.getChildren().add(detailsPane);
} else {
this.getChildren().remove(detailsPane);
}
this.requestLayout();
});
}
@Override
protected double computePrefHeight(double width) {
if (isSelected()) {
return super.computePrefHeight(width)+detailsPane.prefHeight(60);
} else {
return super.computePrefHeight(width);
}
}
@Override
protected void layoutChildren() {
super.layoutChildren();
if (isSelected()) {
double width = getWidth();
double paneHeight = detailsPane.prefHeight(width);
detailsPane.resizeRelocate(0, getHeight()-paneHeight, width, paneHeight);
}
}
});
}
private TableView<Address> constructSubTable(Person person) {
List<Address> addresses = new ArrayList<>(); addresses.add(person.getAddress());
TableView<Address> subTable = new TableView<Address>();
TableColumn<Address, String> streetCol = new TableColumn<Address, String>("Street");
streetCol.setMinWidth(100);
streetCol.setCellValueFactory(new PropertyValueFactory<Address, String>("Street"));
TableColumn<Address, String> cityCol = new TableColumn<Address, String>("City");
cityCol.setMinWidth(100);
cityCol.setCellValueFactory(new PropertyValueFactory<Address, String>("city"));
subTable.setItems(FXCollections.observableArrayList(addresses));
subTable.getColumns().addAll(streetCol, cityCol);
subTable.setPrefHeight(50+(addresses.size()*30));
subTable.setStyle("-fx-border-color: #42bff4;");
return subTable;
}
private ObservableList<Person> getData() {
return FXCollections.observableArrayList(new Person("Jacob", "Smith", "jacob.smith@example.com","Jacob Street","NY"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com","Isabella Street","DL"),
new Person("Ethan", "Williams", "ethan.williams@example.com","Ethan Street"," ML"),
new Person("Emma", "Jones", "emma.jones@example.com","Emma Street","EL"),
new Person("Michael", "Brown", "michael.brown@example.com","Michael Street","ML"));
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Address address;
Person(String fName, String lName, String email,String streetS, String cityS) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
address = new Address(streetS, cityS);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
public static class Address{
private final SimpleStringProperty street;
private final SimpleStringProperty city;
Address(String streetS, String cityS) {
this.street = new SimpleStringProperty(streetS);
this.city = new SimpleStringProperty(cityS);
}
public String getStreet() {
return street.get();
}
public void setStreet(String streetS) {
street.set(streetS);
}
public String getCity() {
return city.get();
}
public void setCity(String cityS) {
city.set(cityS);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment