【问题标题】:How to set multiple levels in a tree grid with Vaadin 8.1?如何使用 Vaadin 8.1 在树形网格中设置多个级别?
【发布时间】:2025-12-11 03:00:01
【问题描述】:

我需要在 vaadin 树网格中显示三个级别。根据 vaadin 文档,我使用“setItems”方法将值设置为树形网格。如何为网格设置第三个嵌套级别。

    TreeGrid<Project> treeGrid = new TreeGrid<>();
    treeGrid.setItems(getProjects(), Project::getSubProjects);
    treeGrid.addColumn(Project::getName).setCaption("Name");
    treeGrid.addColumn(Project::getStatus).setCaption("Status");

我已按照 vaadin 8.1 文档https://vaadin.com/docs/-/part/framework/components/components-treegrid.html中的代码 sn-p 进行操作

【问题讨论】:

    标签: java vaadin vaadin8


    【解决方案1】:

    您有 2 个选项。假设你有类似的东西:

    public class Project {
        private List<Project> subProjects;
    
        public List<Project> getSubProjects(){};
    }
    
    • 第一个也是最简单的解决方案是向树提供一个根项目列表和一个子项目提供者(一种检索给定项目的子项目的方法):@ 987654327@

    • 或者,如果您确实需要,您可以为每个子项列表指定父项,但您可能需要递归执行此操作。来自documentation link you provideddata.addItems(newProject, newProject.getChildren());(或treeGrid.getTreeData().addItems(newProject, newProject.getSubProjects())


    功能齐全的sscce使用第一种方法(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<>();
            addComponent(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);
                    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;
        }
    
    
        // 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) {
                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);
            }
        }
    
    
        // 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) {
                super(name);
                this.hoursDone = hoursDone;
                lastModified = new Date(year - 1900, random.nextInt(12), random.nextInt(10));
            }
    
            @Override
            public int getHoursDone() {
                return hoursDone;
            }
    
            @Override
            public Date getLastModified() {
                return lastModified;
            }
        }
    }
    

    结果:

    【讨论】:

    • addItems 应该递归调用还是我需要提供项目层次结构并调用一次?
    • @4EACH 我相信我在乞讨中回答了这个问题,用 2 个子弹。有什么不清楚的地方吗?
    • 我已经解决了这个问题。