如何从JavaFX中的值集合动态生成树视图

时间:2018-01-26 08:33:32

标签: java javafx treeview

出于学习目的,我想从Enum动态构建一个树视图,我在那里定义了与他们的关系的树项。

MenuContext枚举

public enum MenuContext {
 APP, // Tree menu of application
 DIALOG; // Tree menu on dialog
}

TreeItems枚举

public enum TreeItems {
 AM_ROOT(MenuContext.APP, null, ""),
 NODE_1(MenuContext.APP, AM_ROOT, "Menu node 1"),
 NODE_2(MenuContext.APP, AM_ROOT, "Menu node 2"),
 NODE_2_1(MenuContext.APP, NODE_2, "Menu node 2.1"),
 NODE_2_2(MenuContext.APP, NODE_2, "Menu node 2.2"),
 NODE_2_3(MenuContext.APP, NODE_2, "Menu node 2.3"),
 NODE_2_4(MenuContext.APP, NODE_2, "Menu node 2.4"),
 NODE_3(MenuContext.APP, AM_ROOT, "Menu node 3"),
 NODE_4(MenuContext.APP, AM_ROOT, "Menu node 4"),
 DM_ROOT(MenuContext.DIALOG, null, ""),
 DM_NODE_1(MenuContext.DIALOG, DM_ROOT, "Dialog menu node 1"),
 DM_NODE_2(MenuContext.DIALOG, DM_ROOT, "Dialog menu node 2"),
 DM_NODE_2_1(MenuContext.DIALOG, DM_NODE_2, "Dialog menu node 2.1"),
 DM_NODE_2_2(MenuContext.DIALOG, DM_NODE_2, "Dialog menu node 2.2"),
 DM_NODE_2_3(MenuContext.DIALOG, DM_NODE_2, "Dialog menu node 2.3"),
 DM_NODE_2_4(MenuContext.DIALOG, DM_NODE_2, "Dialog menu node 2.4"),
 DM_NODE_3(MenuContext.DIALOG, DM_ROOT, "Dialog menu node 3");

 // Necessary code to get values of single enum item
}

通过这种结构,我试图按照Answer - fill javaFX treeView dynamically上的答案动态创建树,我已经看到问题和答案被引用到数据库以存储树信息。

所以我的问题是我如何适应,构建算法到Enum数据源,因为当我尝试使用建议的代码动态构建树时,我可以一个接一个地得到树项目列表并且不按父项分组

1 个答案:

答案 0 :(得分:0)

经过多次尝试和失败之后,我发现了一种方法,可以使用这种方法从父对象的一组对象中动态构建树视图。

private TreeView<String> buildTree(MenuContext mC) {
 List<TreeItems> roots = buildParents(mC);
 EnumMap<TreeItems, TreeItem<String>> values = buildTreeValues(mC);
 TreeView<String> tree = new TreeView<>();
 TreeItem<String> root = null;
 int rootsSize = roots.size();
 // Build node w or w/o children in reverse order
 for (int i = rootsSize - 1; i > 0; --i) {
  EnumMap<TreeItems, TreeItem<String>> nodeChildren = getNodeChildren(roots.get(i),values);
  for (Entry<TreeItems, TreeItem<String>> entry : nodeChildren.entrySet()) {
   values.get(roots.get(i)).getChildren().add(entry.getValue());
   values.remove(entry.getKey());
  }
 }
 // Populate tree model
 for (Entry<TreeItems, TreeItem<String>> entry : values.entrySet()) {
  if (entry.getKey().getParent() == null) {
   root = entry.getValue();
  } else {
   if (root == null) {
    root = entry.getValue();
   } else {
    root.getChildren().add(entry.getValue());
   }
  }
 }
 tree.setRoot(root);
 tree.setShowRoot(false);
 return tree;
}

private EnumMap<TreeItems, TreeItem<String>> buildTreeValues(MenuContext mC) {
 EnumMap<TreeItems, TreeItem<String>> treeValues = new EnumMap<>(TreeItems.class);
 for (TreeItems tI : TreeItems.values()) {
  if (tI.getMenuContext().equals(mC)) {
   treeValues.put(tI, new TreeItem<>(tI.getLabel()));
  }
 }
 return treeValues;
}

private List<TreeItems> buildParents(MenuContext mC) {
 List<TreeItems> parents = new ArrayList<>();
 for (TreeItems tI : TreeItems.values()) {
  if (tI.getMenuContext().equals(mC) && !parents.contains(tI.getParent())) {
   parents.add(tI.getParent());
  }
 }
 return parents;
}

private EnumMap<TreeItems, TreeItem<String>> getNodeChildren(TreeItems root,
 EnumMap<TreeItems, TreeItem<String>> values) {
 EnumMap<TreeItems, TreeItem<String>> cNodes = new EnumMap<>(TreeItems.class);
 for (Entry<TreeItems, TreeItem<String>> entry : values.entrySet()) {
  TreeItems parentKey = entry.getKey().getParent();
  if (parentKey != null && root.equals(parentKey)) {
   cNodes.put(entry.getKey(), entry.getValue());
  }
 }
 return cNodes;
}

我已经使用具有三级嵌套的枚举手动测试了实现,并且生成的树显示了由其父级正确分组的值。