I am writing an application which will display information logically represented as a collection of hierarchies of items. There will be a "top-level" list that will display the names of all the root nodes in the collection. When one of the items is selected, another list (the tree grid) will be loaded with the selected root node and I need it to display and provide access to everything in its hierarchy.
I can't figure out how to get the hierarchy to load in the grid.
I have defined a data provider class that extends AbstractBackEndHierarchicalDataProvider
. It is my impression that the purpose of this class is to facilitate retrieving data in a hierarchical relationship. I also have a @Service
class that is called from the provider to do the work. The class (TaskMaster
) that represents the nodes does not contain any references to a "parent" or "children".
Here is the code:
TaskTreeView.java
public class TaskTreeView extends VerticalLayout {
private TreeGrid<TaskMaster> taskGrid;
private TaskMasterDataProvider provider;
private TaskMasterService taskService;
public TaskTreeView(TaskMasterService taskService) {
this.taskService = taskService;
}
// Load the selected task (and its hierarchy).
public void loadTasks(TopLevelTaskView.TaskSelectionEvent event) {
if (event.getSelected() != null) {
updateTree(event.getSelected());
}
}
private void updateTree(TaskMaster task) {
taskGrid.setItems(task);
provider.refreshItem(task, true);
}
private void configureView() {
taskGrid = new TreeGrid<>(TaskMaster.class);
taskGrid.setColumns("name", "type");
taskGrid.setHierarchyColumn("name");
taskGrid.getColumns().forEach(col -> {
col.setAutoWidth(true);
col.setResizable(true);
});
provider = new TaskMasterDataProvider(taskService);
taskGrid.setDataProvider(provider);
add(taskGrid);
}
}
TaskMasterDataProvider.java
public class TaskMasterDataProvider
extends AbstractBackEndHierarchicalDataProvider<TaskMaster, Void> {
private TaskMasterService service;
public TaskMasterDataProvider(TaskMasterService service) {
this.service = service;
}
@Override
public int getChildCount(HierarchicalQuery<TaskMaster, Void> query) {
return service.getChildCount(query.getParent());
}
@Override
public boolean hasChildren(TaskMaster item) {
return service.hasChildren(item);
}
@Override
protected Stream<TaskMaster> fetchChildrenFromBackEnd(HierarchicalQuery<TaskMaster, Void> query) {
return service.getChildren(query.getParent()).stream();
}
}
TaskMasterService.java
@Service
@Transactional
public class TaskMasterService {
private final TaskMasterRepository taskMasterRepo;
private final TaskRelationshipService taskRelationService;
@Autowired
public TaskMasterService(TaskMasterRepository taskMasterRepo,
TaskRelationshipService taskRelationService) {
this.taskMasterRepo = taskMasterRepo;
this.taskRelationService = taskRelationService;
}
...
public int getChildCount(TaskMaster parent) {
return parent != null
? taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).size()
: 0;
}
public boolean hasChildren(TaskMaster parent) {
return parent != null
? !taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).isEmpty()
: false;
}
public List<TaskMaster> getChildren(TaskMaster parent) {
List<TaskMaster> result = new ArrayList<>();
if (parent != null) {
List<TaskRelationship> childRelations = taskRelationService
.getChildRelationsForParent(parent.getInternalTaskID());
childRelations.forEach(relation -> {
result.add(taskMasterRepo.findByInternalTaskID(relation.getChildTaskID()));
});
}
return result;
}
}
When I run the application and select an item from the "top level" list, the tree loads the root node and nothing else. Am I using the provider in the wrong way?
Domain data explanation (as best as I understand it):
TaskMaster
Contains information about "tasks", which is a broad description for a number of things, but is mainly used to define an application menu structure. The task type is one of the following: TASK_VIEW, INTERACTIVE, BATCH, FOLDER, URL, USER_DEFINED. The unique ID is internalTaskID. Note that this is NOT the database key. There is no concept of a "parent" or "children" in this data structure.
TaskRelationship
Contains a parent/child relationship between two "tasks" (i.e. TaskMaster entities).
Example:
In TaskMaster:
{
internalTaskID: "1014",
name: "Manufacturing Tasks",
type: "00", // TASK_VIEW
}
{
internalTaskID: "464E4534",
name: "Manufacturing Inquiries",
type: "07", // FOLDER
}
{
internalTaskID: "4E3CBF33",
name: "Item Ledger",
type: "01", // INTERACTIVE
}
In TaskRelationship:
{
parentTaskID: "1014",
childTaskID: "464E4534",
}
{
parentTaskID: "464E4534",
childTaskID: "4E3CBF33",
}
question from:
https://stackoverflow.com/questions/65937750/vaadin-14-treegrid-grid-not-loading-hierarchy