Просмотр дерева в Nattable

#java #treetable #nattable

#java #treetable #nattable

Вопрос:

Я ищу способ создать представление в виде дерева в Nattable. У меня уже есть NatTable, реализованный с фильтром, сортировкой, …

Но теперь я изучаю таблицу дерева, такую как пример treegridwithcheckboxfields из примеров Nattable. Единственным требованием является то, что я не изменяю свою модель данных для дерева.

У меня есть два разных объекта Company и role. У каждой компании есть все роли. Итак, в этой ситуации мне нужно дерево со всеми компаниями в качестве корневого объекта и всеми ролями под всеми компаниями.

Из примера похоже, что мне нужно создать класс format, который реализует TreeList.Формат, но они используют модель для связывания родительского элемента (я не буду этого делать, потому что это нарушение принципа MVC.

Может ли кто-нибудь помочь мне создать представление treetable в NatTable?

После проверки некоторого примера Natable я получил рабочую таблицу дерева. Но осталась только одна проблема. Родительские элементы отображаются некорректно.

Формат дерева выглядит следующим образом:

 public class TreeFormat implements TreeList.Format<PermissionViewModel> {

public TreeFormat() {
}

@Override
public Comparator getComparator(int depth) {    
    return new Comparator<PermissionViewModel>() {

        @Override
        public int compare(PermissionViewModel object1, PermissionViewModel object2) {

            return object1.getModuleName().compareTo(object2.getModuleName());

        }
    };
}

@Override
public void getPath(List<PermissionViewModel> path, PermissionViewModel element) {
     path.add(element);
     PermissionViewModel parent = element.getParent();
        while (parent != null) {
            path.add(parent);
            parent = parent.getParent();
        }
        Collections.reverse(path);  
}

@Override
public boolean allowsChildren(PermissionViewModel element) {
    return true;
}
  

Модель, которую я использую, является ViewModel и представляет собой взаимно однозначное сопоставление с обычной моделью

 public class PermissionViewModel implements Comparable {

    private PermissionViewModel parent;
    private ArrayList<PermissionViewModel> children = new ArrayList();

    private Integer permissionId;
    private String moduleName;
    private String permissionName;
    private boolean active;
    private boolean on;

    public PermissionViewModel(PermissionViewModel parent, Permission permission) {
        this.parent = parent;
        if (parent != null) {
            parent.addChild(this);
        }

        if(parent == null amp;amp; permission != null)
        {
            this.permissionId = 0;
            this.moduleName = "";
            this.permissionName = permission.getModuleName();
            this.active = false;    
        }           
        else
        {
            this.permissionId = permission.getPermissionId();
            this.moduleName = permission.getModuleName();
            this.permissionName = permission.getPermissionName();
            this.active = permission.isActive();
        }
    }

    public PermissionViewModel getParent() {
        return this.parent;
    }

    public void addChild(PermissionViewModel child) {
        this.children.add(child);
    }

    public List getChildren() {
        return this.children;
    }

    public PermissionViewModel getSelf() {
        return this;
    }

    public boolean isOn() {
        if (this.children.size() == 0) {
            return this.on;
        } else {
            return getCheckBoxState() == CheckBoxStateEnum.CHECKED;
        }
    }

    public void setOn(boolean on) {
        if (this.children.size() == 0) {
            this.on = on;
        } else {
            for (PermissionViewModel child : this.children) {
                child.setOn(on);
            }
        }
    }


    public CheckBoxStateEnum getCheckBoxState() {
        if (this.children.size() == 0) {
            return this.on ? CheckBoxStateEnum.CHECKED
                    : CheckBoxStateEnum.UNCHECKED;
        } else {
            boolean atLeastOneChildChecked = false;
            boolean atLeastOneChildUnchecked = false;

            for (PermissionViewModel child : this.children) {
                CheckBoxStateEnum childCheckBoxState = child.getCheckBoxState();
                switch (childCheckBoxState) {
                    case CHECKED:
                        atLeastOneChildChecked = true;
                        break;
                    case SEMICHECKED:
                        return CheckBoxStateEnum.SEMICHECKED;
                    case UNCHECKED:
                        atLeastOneChildUnchecked = true;
                        break;
                }
            }

            if (atLeastOneChildChecked) {
                if (atLeastOneChildUnchecked) {
                    return CheckBoxStateEnum.SEMICHECKED;
                } else {
                    return CheckBoxStateEnum.CHECKED;
                }
            } else {
                return CheckBoxStateEnum.UNCHECKED;
            }
        }
    }

    @Override
    public int compareTo(Object o) {
        return 0;
    }

    public Integer getPermissionId() {
        return permissionId;
    }

    public String getModuleName() {
        return moduleName;
    }

    public String getPermissionName() {
        return permissionName;
    }

    public boolean isActive() {
        return active;
    }

}
  

Помещение данных в таблицу дерева будет выполняться со следующим источником:

 ArrayList<PermissionViewModel> permissionViewModelsList = new ArrayList<>();
    String previousModule = "";
    PermissionViewModel currentParent = null;

    for (Permission element : repo.getAllData()) {

        if(!previousModule.equals(element.getModuleName()))
        {
            previousModule = element.getModuleName();

            currentParent = new PermissionViewModel(null, element);
            permissionViewModelsList.add(currentParent);

            permissionViewModelsList.add(new PermissionViewModel(currentParent, element));
        }
        else
        {
            permissionViewModelsList.add(new PermissionViewModel(currentParent, element));
        }

    }
    Collections.reverse(permissionViewModelsList);


    permissionTable.setItems(permissionViewModelsList);
    permissionTable.refresh(true);
  

Но когда я смотрю на таблицу, просматриваются корневые элементы, но дочерние элементы корневых элементов неверны. Я просмотрел список элементов, и там я не могу найти никаких проблем. Может кто-нибудь найти проблему, которая у меня есть?

введите описание изображения здесь

Комментарии:

1. Я не понимаю ваших опасений относительно списка деревьев. Формат и MVC. NatTable — это представление и список деревьев. Формат является его частью. Он должен показывать что-то, связанное с моделью. Поэтому я думаю, что это совершенно нормально, что список деревьев. Форматирование как часть представления зависит от модели для построения древовидной структуры. Итак, каковы ваши проблемы в деталях? И как вы хотите построить древовидную структуру из вашей модели данных, не получая информацию из модели?

2. В некоторых ситуациях это может быть нормально. Но в моей ситуации ролям не нужно ничего знать о его родителе (компании). В противном случае мне нужно создать одну и ту же роль для каждой компании (1 роль существует во всех компаниях).

3. Затем вам нужно преобразовать вашу модель данных в модель представления. NatTable работает со списками. И преобразование в дерево выполняется на основе списка. Если этот список не содержит всех компаний и всех ролей, связанных со всеми компаниями, невозможно отобразить такую структуру.

4. Я имею в виду преобразование, создание модели представления из вашей модели данных.

5. Ваш компаратор неверен. Он не учитывает древовидную структуру

Ответ №1:

Я изменил порядок столбцов. Я поместил «Имя модуля» перед столбцом «Имя». И имя родительского модуля было помещено в столбец имени модуля. Это устранило мою проблему.

Проблема в этом случае заключалась в том, что используемый мной компилятор не работает со смешанными данными в одних и тех же полях. Спасибо Дирку Фауту, я нашел это.