TreeTableView: Displaying different data types

ridi


I have a Factory class which contains a list of employees. I want to use a TreeTableView to display the Factory data. It is pretty forward to display the name and the size of a Factory, but i don't know how to display the employees names!

public class Factory {
       private String name;
       private double size;
       private List<Employee> employees;

       public Factory(name, size){this.name=name; this.size=size} 

       // Getters & setters

    }

I want to have the following output:

enter image description here

With the possibilty to fold the factory.

James_D

In a TreeView or TreeTableView all nodes in the tree have to be of the same type. This makes the kind of design you want (which is very natural) something of a pain. Basically, you have to make the type of the TreeView or TreeTableView the most specific superclass of all the types of rows you want in the tree: i.e. in this case the type of the TreeTableView needs to be a superclass of both Employee and Factory. Then the cell value factories on the columns would have to type test the row objects to determine what value to return.

It would be unusual to have an object model in which these were related by inheritance other than both being subclasses of Object, so you probably need a TreeTableView<Object> here.

So roughly speaking (if you are using plain old JavaBean style, instead of the recommended JavaFX properties), you would define something like

TreeTableView<Object> treeTable = new TreeTableView<>();
treeTable.setShowRoot(false);

TreeTableColumn<Object, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
        Factory f = (Factory) rowItem.getValue() ;
        return new SimpleStringProperty(f.getName());
    } else {
        return new SimpleStringProperty("");
    }
});

TreeTableColumn<Object, Number> sizeColumn = new TreeTableColumn<>("Size");
sizeColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
        Factory f = (Factory) rowItem.getValue() ;
        return new SimpleObjectProperty<Number>(Double.valueOf(f.getSize()));
    } else {
        return new SimpleObjectProperty<Number>(null);
    }
});

TreeTableColumn<Object, String> employeeColumn = new TreeTableColumn<>("Employee");
employeeColumn.setCellValueFactory(cellData -> {
    TreeItem<Object> rowItem = cellData.getValue();
    if (rowItem != null && (rowItem.getValue() instanceof Employee)) {
        Employee emp = (Employee) rowItem.getValue() ;
        return new SimpleStringProperty(emp.getName());
    } else {
        return new SimpleStringProperty("");
    }
});

treeTable.getColumns().addAll(nameColumn, sizeColumn, employeeColumn);

and of course you populate it with

// fully initialized list of factories, with employee lists initialized:
List<Factory> factories = ... ;

TreeItem<Object> root = new TreeItem<>(null);
for (Factory factory : factories) {
    TreeItem<Object> factoryItem = new TreeItem<>(factory);
    root.getChildren().add(factoryItem);
    for (Employee emp : factory.getEmployees()) {
        TreeItem<Object> employeeItem = new TreeItem<>(emp);
        factoryItem.getChildren().add(employeeItem);
    }
}
treeTable.setRoot(root);

Here's a simple SSCCE using this:

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;

public class TreeTableExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Object> treeTable = new TreeTableView<>();
        treeTable.setShowRoot(false);

        TreeTableColumn<Object, String> nameColumn = new TreeTableColumn<>("Name");
        nameColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
                Factory f = (Factory) rowItem.getValue() ;
                return new SimpleStringProperty(f.getName());
            } else {
                return new SimpleStringProperty("");
            }
        });

        TreeTableColumn<Object, Number> sizeColumn = new TreeTableColumn<>("Size");
        sizeColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Factory)) {
                Factory f = (Factory) rowItem.getValue() ;
                return new SimpleObjectProperty<Number>(Double.valueOf(f.getSize()));
            } else {
                return new SimpleObjectProperty<Number>(null);
            }
        });

        TreeTableColumn<Object, String> employeeColumn = new TreeTableColumn<>("Employee");
        employeeColumn.setCellValueFactory(cellData -> {
            TreeItem<Object> rowItem = cellData.getValue();
            if (rowItem != null && (rowItem.getValue() instanceof Employee)) {
                Employee emp = (Employee) rowItem.getValue() ;
                return new SimpleStringProperty(emp.getName());
            } else {
                return new SimpleStringProperty("");
            }
        });

        treeTable.getColumns().addAll(nameColumn, sizeColumn, employeeColumn);

        List<Factory> factories = createData();
        TreeItem<Object> root = new TreeItem<>(null);
        for (Factory factory : factories) {
            TreeItem<Object> factoryItem = new TreeItem<>(factory);
            root.getChildren().add(factoryItem);
            for (Employee emp : factory.getEmployees()) {
                TreeItem<Object> employeeItem = new TreeItem<>(emp);
                factoryItem.getChildren().add(employeeItem);
            }
        }
        treeTable.setRoot(root);

        Scene scene = new Scene(treeTable, 800, 800);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private List<Factory> createData() {
        String[][] empNames = {
                {"John", "Jane", "Mary"},
                {"Susan", "Mike"},
                {"Alex", "Francois", "Joanne"}
        };
        List<Factory> factories = new ArrayList<>();
        for (String[] emps : empNames) {
            int count = factories.size()+1 ;
            Factory f = new Factory("Factory "+ count, count*10);
            for (String empName : emps) {
                f.getEmployees().add(new Employee(empName));
            }
            factories.add(f);
        }
        return factories ;
    }

    public static class Employee {
        private String name ;

        public Employee(String name) {
            this.name = name ;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }


    }

    public class Factory {
        private String name ;
        private double size ;
        private List<Employee> employees ;

        public Factory(String name, double size) {
            this.name = name ;
            this.size = size ;
            this.employees = new ArrayList<>();
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public double getSize() {
            return size;
        }

        public void setSize(double size) {
            this.size = size;
        }

        public List<Employee> getEmployees() {
            return employees;
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}

enter image description here


Another approach, which I think is a bit artificial, is to create a class representing the row in the table view, and then to make Factory and Employee subclasses of it:

public abstract class EmploymentEntity {

    public String getName() {
        return null ;
    }

    public Double getSize() {
        return null ;
    }

    public String getEmployeeName {
        return null ;
    }
}

then

public class Employee extends EmploymentEntity {
    private String name ;

    public Employee(String name) {
        this.name = name ;
    }

    @Override
    public String getEmployeeName() {
        return name ;
    }

    public void setEmployeeName(String name) {
        this.name = name ; 
    }
}

and

public class Factory extends EmploymentEntity {

    private String name ;
    private double size ;
    private List<Employee> employees ;

    public Factory(String name, double size) {
        this.name = name ;
        this.size = size ;
        this.employees = new ArrayList<>();
    }

    @Override
    public String getName() {
        return name ;
    }

    public void setName(String name) {
        this.name = name ;
    }

    @Override
    public Double getSize() {
        return size ;
    }

    public void setSize(double size) {
        this.size = size ;
    }

    public List<Employee> getEmployees() {
        return employees ;
    }
}

This object model is really unnatural (to me, anyway), but it does make the table a little easier:

TreeTableView<EmploymentEntity> treeTable = new TreeTableView<>();
TreeTableColumn<EmploymentEntity, String> nameColumn = new TreeTableColumn<>("Name");
nameColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getValue().getName()));
TreeTableColumn<EmploymentEntity, Number> sizeColumn = new TreeTableColumn<>("Size");
sizeColumn.setCellValueFactory(cellData -> new SimpleObjectProperty<Number>(cellData.getValue().getValue().getSize()));
TreeTableColumn<EmploymentEntity, String> employeeColumn = new TreeTableColumn<>("Employee");
employeeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getValue().getEmployeeName()));
// etc...

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Displaying data in a different manner

From Dev

Displaying retrieve data in different table

From Dev

Displaying retrieve data in different table

From Dev

Operations on different data types

From Dev

Displaying different data through portrait/landscape view

From Dev

Displaying GPS data with different colors in R

From Dev

Share data with different types in UIActivityViewController

From Dev

Constructor and different data types are confusing

From Dev

Mutable list with different types of data

From Dev

Mutable list with different types of data

From Dev

Different Data types Order By in SQL

From Dev

Object data with 2 different types

From Dev

Java Fx TreeTableView different Context Menu items

From Dev

Java Fx TreeTableView different Context Menu items

From Dev

Displaying retrieved data from GAE datastore in two different html tables

From Dev

SSRS Chart. Displaying data in a different way than the dataset

From Dev

Displaying data from another two different tables on an index page

From Dev

Winform Chart control - to keep displaying same bar width for different data

From Dev

Can a linkedlist store different data types?

From Dev

Matlab array having columns of different data types?

From Dev

Can mysql join occur on different data types

From Dev

Spring Data Mongodb - repository for collection with different types

From Dev

LINQ Join On Multiple Columns With Different Data Types

From Dev

how size of a structure varies with different data types

From Dev

core data: save different types as the same attribute

From Dev

Use a single method to return data with different types

From Dev

Can a method be able to return different data types?

From Dev

Elasticsearch mapping - different data types in same field

From Dev

Single struct adjusting methods to different data types

Related Related

  1. 1

    Displaying data in a different manner

  2. 2

    Displaying retrieve data in different table

  3. 3

    Displaying retrieve data in different table

  4. 4

    Operations on different data types

  5. 5

    Displaying different data through portrait/landscape view

  6. 6

    Displaying GPS data with different colors in R

  7. 7

    Share data with different types in UIActivityViewController

  8. 8

    Constructor and different data types are confusing

  9. 9

    Mutable list with different types of data

  10. 10

    Mutable list with different types of data

  11. 11

    Different Data types Order By in SQL

  12. 12

    Object data with 2 different types

  13. 13

    Java Fx TreeTableView different Context Menu items

  14. 14

    Java Fx TreeTableView different Context Menu items

  15. 15

    Displaying retrieved data from GAE datastore in two different html tables

  16. 16

    SSRS Chart. Displaying data in a different way than the dataset

  17. 17

    Displaying data from another two different tables on an index page

  18. 18

    Winform Chart control - to keep displaying same bar width for different data

  19. 19

    Can a linkedlist store different data types?

  20. 20

    Matlab array having columns of different data types?

  21. 21

    Can mysql join occur on different data types

  22. 22

    Spring Data Mongodb - repository for collection with different types

  23. 23

    LINQ Join On Multiple Columns With Different Data Types

  24. 24

    how size of a structure varies with different data types

  25. 25

    core data: save different types as the same attribute

  26. 26

    Use a single method to return data with different types

  27. 27

    Can a method be able to return different data types?

  28. 28

    Elasticsearch mapping - different data types in same field

  29. 29

    Single struct adjusting methods to different data types

HotTag

Archive