I'm looking for a way to create a treeTable view in Nattable. I already have a NatTable implemented with filter, sorting, ...
But now I'm looking into a TreeTable like the TreeGridWithCheckBoxFieldsExample from the Nattable examples. The only requirement is that I do not change my datamodel for the tree.
I have two different objects Company and role. Every company does has all the roles. So in this situation I need a tree with all the companies as root object and all the roles beneath all the companies.
From the example it looks like I need to create a format class that implements the TreeList.Format but they are using the model to link the parent (I will not do this because it's a violation of the MVC principle.
Can someone get me on track to create a treetable view in NatTable?
After checking some example of Natable I got a working treeTable. But have only one problem left. The parent items are not correctly shown.
The treeFormat looks like:
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;
}
The model that I use is a viewModel and is a one to one map to the normal model
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 && 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;
}
}
Putting data in the tree table will be done with following source:
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);
But when I look at the table the root elements are viewed but the childeren of the root elements are wrong. I viewed the list of elements and there I can't find any issues. Can someone find the issue that I have?
I changed to order of the columns. I placed the "Module Name" before the "Name" column. And the parent module name has been placed in the module name column. This fixed my problem.
The issue in this case was that the comperator that I used is not working on mixed data in the same fields. Tnx to Dirk Fauth I found it.