How to set multiple levels in a tree grid with Vaadin 8.1?

I need to display three levels in a vaadin tree grid. I use the ‘setItems’ method to set values to the tree grid as per the vaadin documentation. How can I set a third nested level to the grid.

    TreeGrid<Project> treeGrid = new TreeGrid<>();
    treeGrid.setItems(getProjects(), Project::getSubProjects);

I’ve followed the code snippet in the vaadin 8.1 documentation

You have 2 options. Suppose you have something similar to:

public class Project {
    private List<Project> subProjects;

    public List<Project> getSubProjects(){};
  • the first and simplest solution, is to supply a list of root projects and a child item provider (a means of retrieving the child projects for a given project) to the tree: treeGrid.setItems(rootProjects, Project::getSubProjects);

  • alternatively, if you really need to, you can specify the parent for each list of child items, but you may need to do this recursively. From the documentation link you provided: data.addItems(newProject, newProject.getChildren()); (or treeGrid.getTreeData().addItems(newProject, newProject.getSubProjects()))

Fully functional sscce using the first method (stolen from the Vaadin sampler):

public class BasicTreeGrid extends VerticalLayout {

    // used to generate some random data
    private final Random random = new Random();

    public BasicTreeGrid() {
        // basic tree setup
        TreeGrid<Project> treeGrid = new TreeGrid<>();
        treeGrid.addColumn(Project::getName).setCaption("Project Name").setId("name-column");
        treeGrid.addColumn(Project::getHoursDone).setCaption("Hours Done");
        treeGrid.addColumn(Project::getLastModified).setCaption("Last Modified");

        // some listeners for interaction
        treeGrid.addCollapseListener(event -> Notification
                .show("Project '" + event.getCollapsedItem().getName() + "' collapsed.", Notification.Type.TRAY_NOTIFICATION));
        treeGrid.addExpandListener(event -> Notification
                .show("Project '" + event.getExpandedItem().getName() + "' expanded.", Notification.Type.TRAY_NOTIFICATION));

        // add the list of root projects and specify a provider of sub-projects
        treeGrid.setItems(generateProjectsForYears(2010, 2016), Project::getSubProjects);

    // generate some random projects
    private List<Project> generateProjectsForYears(int startYear, int endYear) {
        List<Project> projects = new ArrayList<>();

        for (int year = startYear; year <= endYear; year++) {
            Project yearProject = new Project("Year " + year);

            for (int i = 1; i < 2 + random.nextInt(5); i++) {
                Project customerProject = new Project("Customer Project " + i);
                        new LeafProject("Implementation", random.nextInt(100), year),
                        new LeafProject("Planning", random.nextInt(10), year),
                        new LeafProject("Prototyping", random.nextInt(20), year)));
        return projects;

    // basic parent (or intermediate child) bean used for easy binding
    class Project {
        private List<Project> subProjects = new ArrayList<>();
        private String name;

        public Project(String name) {
   = name;

        public String getName() {
            return name;

        public List<Project> getSubProjects() {
            return subProjects;

        public void setSubProjects(List<Project> subProjects) {
            this.subProjects = subProjects;

        public void addSubProject(Project subProject) {

        public int getHoursDone() {
            return getSubProjects().stream().map(project -> project.getHoursDone()).reduce(0, Integer::sum);

        public Date getLastModified() {
            return getSubProjects().stream().map(project -> project.getLastModified()).max(Date::compareTo).orElse(null);

    // basic final child (can not have other children) bean used for easy binding
    class LeafProject extends Project {
        private int hoursDone;
        private Date lastModified;

        public LeafProject(String name, int hoursDone, int year) {
            this.hoursDone = hoursDone;
            lastModified = new Date(year - 1900, random.nextInt(12), random.nextInt(10));

        public int getHoursDone() {
            return hoursDone;

        public Date getLastModified() {
            return lastModified;