How to add image / icon to hierarchyColumn in TreeDataGrid

Hi,
I am trying to add an icon with text or only an icon in the hierarchyColumn in the TreeDataGrid. I can understand that i have to use the custom renderer or using the partNameGenerator. So, Please help me with sample code.

Example as shown below:
image

Thanks.

Hello!

I understand your confuse, if your create generator for column, hierarchy from datagrid disappears, thats uncommon behaviour. So, i did following steps to add “generatable” column that can use as hierarchy column:

Remark: i use kotlin, so maybe i take mistakes or typos inside java code.

  1. I used UserListView as base view for my experiments
  2. Go to the user-list-view.xml
  3. See following code:
    <dataGrid id="usersDataGrid"
                       width="100%"
                       minHeight="20em"
                       dataContainer="usersDc">
             <actions>
                 ...
             </actions>
             <columns resizable="true">
                 <column property="username"/>
                 <column property="firstName"/>
                 <column property="lastName"/>
                 <column property="email"/>
                 <column property="timeZoneId"/>
                 <column property="active"/>
             </columns>
         </treeDataGrid>
    
  4. Change userDataGrid type to treeDataGrid:
    <treeDataGrid id="usersDataGrid"
                      width="100%"
                      minHeight="20em"
                      dataContainer="usersDc"
                      hierarchyProperty="dependsOn"> thats my hierarchy property
            <actions>
                ... same
            </actions>
            <columns resizable="true">
                ... same
            </columns>
        </treeDataGrid>
    
  5. We need to subscribe BeforeShowEvent, inside it remove our first column “username”, generate new column that would be not a column, but HierarchyColumn
    @ViewComponent
    private TreeDataGrid<User> usersDataGrid; 
    
    @Subscribe
    public void onBeforeShow(BeforeShowEvent event) {
        var columns = usersDataGrid.getColumns();
    
        columns.forEach(it -> usersDataGrid.removeColumns(it));
    
        var addComponentHierarchyColumn = usersDataGrid.addComponentHierarchyColumn((user) -> {
            var horizontalLayout = new HorizontalLayout();
           // here you can do anything to provide information about user; use this horizontalLayout to place your components
            horizontalLayout.add(new Avatar());
            horizontalLayout.add(new Text(user.username));
            return horizontalLayout;
        });
    
        addComponentHierarchyColumn.setHeader("Username");
    }
    
  6. Result
    image
  7. Let’s add columns:
    • remove columns from xml descriptor;
    • programmatically add those columns;
    • getPropertyValueByNameReflection method is omitted because i use Kotlin; you need to impement this method on you own
    @ViewComponent
    private TreeDataGrid<User> usersDataGrid;
    
    @Subscribe
    public void onBeforeShow(BeforeShowEvent event) {
        var columns = usersDataGrid.getColumns()
    
        columns.forEach(it -> usersDataGrid.removeColumns(it));
    
    
        var addComponentHierarchyColumn = usersDataGrid.addComponentHierarchyColumn((user) -> {
            var horizontalLayout = new HorizontalLayout();
            // here you can do anything to provide information about user; use this horizontalLayout to place your components
            horizontalLayout.add(new Avatar());
            horizontalLayout.add(new Text(user.username));
            return horizontalLayout;
        });
    
        addComponentHierarchyColumn.setHeader("Username");
    
        Lis.of("firstName", "lastName", "email", "active", "timeZoneId").forEach(propName -> {
            usersDataGrid.addComponentColumn({ user -> {
                String propertyValue = getPropertyValueByNameReflection(user, propName);
                return new Text(propertyValue);
            })
           .setHeader(propName);
        }
    
  8. Final result:
    image
    image
    image

Kotlin project: https://github.com/KartnDev/SearchDymanicAttr

Regards,
Dmitry

Hi all,
Here is my code look like Dmitry Cherkasov suggestion, but no need remove all column.

@Subscribe
public void onInit(final InitEvent event) {
    //remove column by key
    if(assetsDataGrid.getColumnByKey("name") !=null) {
        assetsDataGrid.removeColumn(assetsDataGrid.getColumnByKey("name"));
    }

    //Add hierarchy column
    TreeDataGrid.Column<Asset> nameColumn=   treeDataGrid.addComponentHierarchyColumn(asset -> {
        Icon icon ;
        if (Boolean.TRUE.equals(asset.getIsFolder())){
             icon = ComponentUtils.parseIcon("vaadin:folder");
            icon.setColor("#ddd009");
        }else {
             icon = ComponentUtils.parseIcon("vaadin:file");
            icon.setColor("#8383f7");
        }
        icon.setSize("0.9em");
        Span name = new Span(asset.getName());
        HorizontalLayout row = new HorizontalLayout(icon, name);
        row.setAlignItems(FlexComponent.Alignment.CENTER);
        row.setSpacing(true);
        return row;
    }).setHeader("Name")
      .setAutoWidth(true)
      .setResizable(true);

    //set position for hierarchy column
    treeDataGrid.setColumnPosition(nameColumn,0);

}

The result:
image

2 Likes