Search code examples
vaadintreegridvaadin-flow

Vaadin TreeGrid has no expand or collapse icon


I use Vaadin to create a simple Web Application that contains a single TreeGrid. The TreeGrid shows up, but there is no handle to expand or collapse a root element ("Year 2010" or "Year 2011") although there are children. When I use expand(..) Method, the tree is expanded (as shown in the screenshot), but there is no icon to collapse it. In the screenshot below "Year 2011" is the expanded root node where "Customer Project1" and "Customer Project 2" are children. The project is build with Maven, I use vaadin-bom version 13.0.2 with vaadin-grid-flow-3.0.3.jar. Below the screenshot there is the code I use. I think the problem must be somewhere in method createTreeGrid(). The working example from Vaadin can be found here Vaadin example

So anyone any ideas on how to solve this? any help appreciated... :-)

Thorsten

Screenshot

package hello;


@Route
public class MainView extends VerticalLayout
{

public MainView()
{
    add( createTreeGrid() );
}

private TreeGrid<Project> createTreeGrid()
{
    TreeGrid<Project> treeGrid = new TreeGrid<>();
    final List<Project> generateProjectsForYears = generateProjectsForYears( 2010, 2016 );
    treeGrid.setItems( generateProjectsForYears, Project::getSubProjects );

    treeGrid.addColumn( Project::getName ).setHeader( "Project Name" ).setId( "name-column" );
    treeGrid.addColumn( Project::getHoursDone ).setHeader( "Hours Done" );
    treeGrid.addColumn( Project::getLastModified ).setHeader( "Last Modified" );

    treeGrid.expand( generateProjectsForYears.get( 1 ) );  // works!

    return treeGrid;
}

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 );

        Random random = new Random();

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

private class Project
{

    private List<Project> subProjects = new ArrayList<>();
    private String name;

    public Project( String name )
    {
        this.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 )
    {
        subProjects.add( 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 );
    }
}

private class LeafProject extends Project
{

    private int hoursDone;
    private Date lastModified;

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

    @Override
    public int getHoursDone()
    {
        return hoursDone;
    }

    @Override
    public Date getLastModified()
    {
        return lastModified;
    }
}

}

Solution

  • You have to define a hierarchy column.

    So simply replace

    treeGrid.addColumn( Project::getName ).setHeader( "Project Name" ).setId( "name-column" );

    with

    treeGrid.addHierarchyColumn( Project::getName ).setHeader( "Project Name" ).setId( "name-column" );