Le Tutoriel de JavaFX TreeTableView

View more categories:

1- JavaFX TreeTableView

JavaFX vous fournit la classe TreeTableView, il est utilisé avec Treeltem, TreetableColomn et TreeTableCell vous aide à afficher les données  sous forme de tableau (Tabulaire) en même temps sous forme arbre. Vous pouvez voir l'illustration ci-dessous:
 
De même que   TableView vous pouvez créer les colonnes imbriquées. Pour créer  TreeTableView vous devez:
  1. Ajouter TreeItem à TreeTableView pour avoir un structure de l'arbre.
  2. Definir les colonnes du tableau.
  3. Definir la manière d'afficher les données sur chaque cellule via la méthode  TreeTableColumn.setCellValueFactory.

2- Exemple avec TreeTableView

Créer un objet  TreeTableView et ajouter des colonnes ( TreeTableColumn).
TreeTableView<Employee> treeTableView = new TreeTableView<Employee>();

// Create column EmpNo (Data type of String).
TreeTableColumn<Employee, String> empNoCol //
      = new TreeTableColumn<Employee, String>("Emp No");

.....

// Add columns to TreeTable.
treeTableView.getColumns().addAll(empNoCol, fullNameCol,
               positionCol, genderCol, singleCol);
Créer  TreeItem et ajouter à  TreeTableView pour avoir une structure de l'arbre:
// Data
Employee empBoss = new Employee("E00", "Abc@gmail.com", //
       "Boss", "Boss", "Manager", "M", false);

Employee empSmith = new Employee("E01", "Smith@gmail.com", //
       "Susan", "Smith", "Salesman", "F", true);

Employee empMcNeil = new Employee("E02", "McNeil@gmail.com", //
       "Anne", "McNeil", "Cleck", "M", false);

// Root Item
TreeItem<Employee> itemRoot = new TreeItem<Employee>(empBoss);
TreeItem<Employee> itemSmith = new TreeItem<Employee>(empSmith);
TreeItem<Employee> itemMcNeil = new TreeItem<Employee>(empMcNeil);

itemRoot.getChildren().addAll(itemSmith, itemMcNeil);

// Set root Item for Tree
treeTableView.setRoot(itemRoot);
Définir la manière d'afficher les données sur chaque cellule de l'arbre.
// Defines how to fill data for each cell.
// Get value from property of Employee.

empNoCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("empNo"));
firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("firstName"));
lastNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("lastName"));
positionCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("position"));
genderCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("gender"));
singleCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, Boolean>("single"));
Voir l'exemple complet:
TreeTableViewDemo.java
package org.o7planning.javafx.treetableview;

import org.o7planning.javafx.model.Employee;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TreeTableViewDemo extends Application {

    @Override
    public void start(Stage stage) {

        TreeTableView<Employee> treeTableView = new TreeTableView<Employee>();

        // Create column EmpNo (Data type of String).
        TreeTableColumn<Employee, String> empNoCol //
                = new TreeTableColumn<Employee, String>("Emp No");

        // Create column FullName (Data type of String).
        TreeTableColumn<Employee, String> fullNameCol//
                = new TreeTableColumn<Employee, String>("Full Name");

        // Create 2 sub column for FullName.
        TreeTableColumn<Employee, String> firstNameCol //
                = new TreeTableColumn<Employee, String>("First Name");

        TreeTableColumn<Employee, String> lastNameCol //
                = new TreeTableColumn<Employee, String>("Last Name");

        // Add sub columns to the FullName
        fullNameCol.getColumns().addAll(firstNameCol, lastNameCol);

        // Gender Column
        TreeTableColumn<Employee, String> genderCol //
                = new TreeTableColumn<Employee, String>("Gender");

        // Position Column
        TreeTableColumn<Employee, String> positionCol //
                = new TreeTableColumn<Employee, String>("Position");

        // Single? Column
        TreeTableColumn<Employee, Boolean> singleCol//
                = new TreeTableColumn<Employee, Boolean>("Single?");

        // Defines how to fill data for each cell.
        // Get value from property of Employee.
        empNoCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("empNo"));
        firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("firstName"));
        lastNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("lastName"));
        positionCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("position"));
        genderCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("gender"));
        singleCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, Boolean>("single"));

        // Add columns to TreeTable.
        treeTableView.getColumns().addAll(empNoCol, fullNameCol,positionCol, genderCol, singleCol);

        // Data
        Employee empBoss = new Employee("E00", "Abc@gmail.com", //
                "Boss", "Boss", "Manager", "M", false);

        Employee empSmith = new Employee("E01", "Smith@gmail.com", //
                "Susan", "Smith", "Salesman", "F", true);

        Employee empMcNeil = new Employee("E02", "McNeil@gmail.com", //
                "Anne", "McNeil", "Cleck", "M", false);

        // Root Item
        TreeItem<Employee> itemRoot = new TreeItem<Employee>(empBoss);
        TreeItem<Employee> itemSmith = new TreeItem<Employee>(empSmith);
        TreeItem<Employee> itemMcNeil = new TreeItem<Employee>(empMcNeil);

        itemRoot.getChildren().addAll(itemSmith, itemMcNeil);
        treeTableView.setRoot(itemRoot);
        //
        StackPane root = new StackPane();
        root.setPadding(new Insets(5));
        root.getChildren().add(treeTableView);

        stage.setTitle("TreeTableView (o7planning.org)");

        Scene scene = new Scene(root, 450, 300);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Employee.java
package org.o7planning.javafx.model;

public class Employee {

    private String empNo;
    private String firstName;
    private String lastName;
    private String email;
    private String position;
    private String gender;

    private boolean single;

    public Employee(String empNo, String email, //
            String firstName, String lastName, String position, String gender, boolean single) {
        this.empNo = empNo;
        this.email = email;
        this.firstName = firstName;
        this.lastName = lastName;
        this.position = position;
        this.gender = gender;
        this.single = single;
    }

    public String getEmpNo() {
        return empNo;
    }

    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public boolean isSingle() {
        return single;
    }

    public void setSingle(boolean single) {
        this.single = single;
    }

}

3- Modifier les données sur TreeTableView

Vous pouvez modifier directement sur TreeTableView, les données seront Mises dans model. L'image ci-dessous illustre un TreeTableView peut éditer.
 

setCellFactory & setCellValueFactory

treeTableColumn.setCellValueFactory
  • Mode spécifiant  pour récupérer les données, mais que lesdonnées seront affichées sur la cellule de TreeTableView.
treeTableColumn.setCellFactory
  • Mode .spécifiant est mise à tirer (rendu) un contrôle (Contrôles) pendant que l'utilisateur modifie les données sur la cellule.

onCellEditComit

Ensuite vous devez définir la fa çon dont les nouvelles données seront mises à jour pour Model, en utilisant les méthodes treeTableColumn.setOnEditCommit. Apres l'utilisateur a fait la modification sur la cellule  TreeTableView les nouvelles données seront mises à jour pour Model.
Avec les cellules montrent CheckBox sur TableView:
Notez que les CheckBoxTreeTableCell dessiner (rendre) Checkbox «en direct», ce qui signifie que les CheckBox est toujours interactive et peut sélectionner ou désélectionner directement par l'utilisateur. Cela signifie qu'il ne faut pas être nécessaire passer à l'état de la cellule (souvent pour calibrer les utilisateurs de transition cellulaire double-cliquez sur la cellule). Un effet secondaire de cela est que les callbacks d'édition habituelles (comme onCommitEdit) ne seront pas appelés. Si vous souhaitez être informé des modifications, vous devez travailler avec l'observation (Observer) attributs booléens sont manipulés par le Checkbox.
 
Voir l'exemple complet:
TreeTableViewEditDemo.java
package org.o7planning.javafx.treetableview;

import org.o7planning.javafx.model.Employee;
import org.o7planning.javafx.model.Gender;

import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.CheckBoxTreeTableCell;
import javafx.scene.control.cell.ComboBoxTreeTableCell;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TreeTableViewEditDemo extends Application {

    @Override
    public void start(Stage stage) {

        TreeTableView<Employee> treeTableView = new TreeTableView<Employee>();
        treeTableView.setEditable(true);

        // Create column EmpNo (Data type of String).
        TreeTableColumn<Employee, String> empNoCol //
                = new TreeTableColumn<Employee, String>("Emp No");

        // Create column FullName (Data type of String).
        TreeTableColumn<Employee, String> fullNameCol//
                = new TreeTableColumn<Employee, String>("Full Name");

        // Create 2 sub column for FullName.
        TreeTableColumn<Employee, String> firstNameCol //
                = new TreeTableColumn<Employee, String>("First Name");

        TreeTableColumn<Employee, String> lastNameCol //
                = new TreeTableColumn<Employee, String>("Last Name");

        // Add sub columns to the FullName
        fullNameCol.getColumns().addAll(firstNameCol, lastNameCol);

        // Gender Column
        TreeTableColumn<Employee, Gender> genderCol //
                = new TreeTableColumn<Employee, Gender>("Gender");
        genderCol.setMinWidth(90);

        // Position Column
        TreeTableColumn<Employee, String> positionCol //
                = new TreeTableColumn<Employee, String>("Position");

        // Single? Column
        TreeTableColumn<Employee, Boolean> singleCol//
                = new TreeTableColumn<Employee, Boolean>("Single?");

        // Add columns to TreeTable.
        treeTableView.getColumns().addAll(empNoCol, fullNameCol, positionCol, genderCol, singleCol);

        // Data
        Employee empBoss = new Employee("E00", "Abc@gmail.com", //
                "Boss", "Boss", "Manager", "M", false);

        Employee empSmith = new Employee("E01", "Smith@gmail.com", //
                "Susan", "Smith", "Salesman", "F", true);

        Employee empMcNeil = new Employee("E02", "McNeil@gmail.com", //
                "Anne", "McNeil", "Cleck", "M", false);

        // Root Item
        TreeItem<Employee> itemRoot = new TreeItem<Employee>(empBoss);
        TreeItem<Employee> itemSmith = new TreeItem<Employee>(empSmith);
        TreeItem<Employee> itemMcNeil = new TreeItem<Employee>(empMcNeil);

        itemRoot.getChildren().addAll(itemSmith, itemMcNeil);
        treeTableView.setRoot(itemRoot);

        // Defines how to fill data for each cell.
        // Get value from property of Employee.
        empNoCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("empNo"));
        firstNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("firstName"));
        lastNameCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("lastName"));
        positionCol.setCellValueFactory(new TreeItemPropertyValueFactory<Employee, String>("position"));

        // GENDER (COMBO BOX).
        genderCol.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<Employee, Gender>, //
        ObservableValue<Gender>>() {

            @Override
            public ObservableValue<Gender> call(TreeTableColumn.CellDataFeatures<Employee, Gender> param) {
                TreeItem<Employee> treeItem = param.getValue();
                Employee emp = treeItem.getValue();
                // F,M
                String genderCode = emp.getGender();
                Gender gender = Gender.getByCode(genderCode);
                return new SimpleObjectProperty<Gender>(gender);
            }
        });
        ObservableList<Gender> genderList = FXCollections.observableArrayList(//
                Gender.values());
        genderCol.setCellFactory(ComboBoxTreeTableCell.forTreeTableColumn(genderList));

        // After user edit on cell, update to Model.
        genderCol.setOnEditCommit(new EventHandler<TreeTableColumn.CellEditEvent<Employee, Gender>>() {

            @Override
            public void handle(TreeTableColumn.CellEditEvent<Employee, Gender> event) {
                TreeItem<Employee> item = event.getRowValue();
                Employee emp = item.getValue();
                Gender newGender = event.getNewValue();
                emp.setGender(newGender.getCode());
                System.out.println("Single column commit. new gender:" +newGender);
                System.out.println("EMP:"+emp.isSingle());
            }
        });

        // ==== SINGLE? (CHECH BOX) ===
        singleCol.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<Employee, Boolean>, //
        ObservableValue<Boolean>>() {

            @Override
            public ObservableValue<Boolean> call(TreeTableColumn.CellDataFeatures<Employee, Boolean> param) {
                TreeItem<Employee> treeItem = param.getValue();
                Employee emp = treeItem.getValue();
                SimpleBooleanProperty booleanProp= new SimpleBooleanProperty(emp.isSingle());
               
                // Note: singleCol.setOnEditCommit(): Not work for
                // CheckBoxTreeTableCell.
                // When "Single?" column change.
                booleanProp.addListener(new ChangeListener<Boolean>() {

                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
                            Boolean newValue) {
                        emp.setSingle(newValue);
                    }                     
                });
                return booleanProp;
            }
        });
 
       
         singleCol.setCellFactory(new Callback<TreeTableColumn<Employee,Boolean>,TreeTableCell<Employee,Boolean>>() {
            @Override
            public TreeTableCell<Employee,Boolean> call( TreeTableColumn<Employee,Boolean> p ) {
                CheckBoxTreeTableCell<Employee,Boolean> cell = new CheckBoxTreeTableCell<Employee,Boolean>();
                cell.setAlignment(Pos.CENTER);
                return cell;
            }
        });

        //
        StackPane root = new StackPane();
        root.setPadding(new Insets(5));
        root.getChildren().add(treeTableView);

        stage.setTitle("TreeTableView (o7planning.org)");

        Scene scene = new Scene(root, 450, 300);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Gender.java
package org.o7planning.javafx.model;

public enum Gender {

    FEMALE("F", "Famale"), MALE("M", "Male");

    private String code;
    private String text;

    private Gender(String code, String text) {
        this.code = code;
        this.text = text;
    }

    public String getCode() {
        return code;
    }

    public String getText() {
        return text;
    }

    public static Gender getByCode(String genderCode) {
        for (Gender g : Gender.values()) {
            if (g.code.equals(genderCode)) {
                return g;
            }
        }
        return null;
    }

    @Override
    public String toString() {
        return this.text;
    }

}

View more categories: