JavaFX:领域对象转换为TreeView的实现咨询
嘿,我来帮你搞定这个TreeView的实现!根据你给出的嵌套领域对象结构和想要的树形展示效果,我会分步骤给你清晰的实现方案——不管你用JavaFX、Swing还是其他UI框架,核心思路都是一致的:递归遍历层级对象,创建对应树节点并建立父子关系。
首先,先明确两种可能的展示结构(因为你给出的示例有点简化,我都给你覆盖到):
方案1:符合对象依赖关系的嵌套结构(推荐)
这是最贴合你Workflow → Sheet → Task依赖关系的结构,展开后是这样的:
-Workflow - 员工入职流程 - Sheets - 入职申请表 - Tasks - 填写基本信息 - 部门审核 - 转正申请表 - Tasks - 提交转正申请 - 经理审批
JavaFX实现示例
先写一个构建TreeView的工具类,负责把领域对象转换成TreeItem节点:
import javafx.scene.control.TreeItem; import java.util.List; public class WorkflowTreeBuilder { // 从Workflow对象构建TreeView的根节点 public static TreeItem<String> buildNestedTree(Workflow workflow) { // 顶级节点:Workflow TreeItem<String> root = new TreeItem<>("Workflow"); root.setExpanded(true); // 默认展开 // 添加Workflow名称节点 TreeItem<String> workflowNameNode = new TreeItem<>(workflow.getName()); root.getChildren().add(workflowNameNode); // 创建Sheets父节点 TreeItem<String> sheetsParentNode = new TreeItem<>("Sheets"); root.getChildren().add(sheetsParentNode); // 遍历每个Sheet,构建子节点 for (Sheet sheet : workflow.getSheets()) { TreeItem<String> sheetNameNode = new TreeItem<>(sheet.getName()); sheetsParentNode.getChildren().add(sheetNameNode); // 创建当前Sheet的Tasks父节点 TreeItem<String> tasksParentNode = new TreeItem<>("Tasks"); sheetNameNode.getChildren().add(tasksParentNode); // 遍历每个Task,添加到Tasks节点下 for (Task task : sheet.getTasks()) { tasksParentNode.getChildren().add(new TreeItem<>(task.getName())); } } return root; } }
然后在JavaFX应用中使用这个工具类:
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.TreeView; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class WorkflowTreeApp extends Application { @Override public void start(Stage stage) { // 构造测试数据 Task task1 = new Task("填写基本信息"); Task task2 = new Task("部门审核"); Sheet sheet1 = new Sheet("入职申请表"); sheet1.getTasks().addAll(task1, task2); Task task3 = new Task("提交转正申请"); Task task4 = new Task("经理审批"); Sheet sheet2 = new Sheet("转正申请表"); sheet2.getTasks().addAll(task3, task4); Workflow workflow = new Workflow("员工入职流程"); workflow.getSheets().addAll(sheet1, sheet2); // 构建TreeView并显示 TreeItem<String> root = WorkflowTreeBuilder.buildNestedTree(workflow); TreeView<String> treeView = new TreeView<>(root); VBox layout = new VBox(treeView); Scene scene = new Scene(layout, 350, 450); stage.setTitle("Workflow TreeView"); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
方案2:你给出的平级结构
如果你确实想要三个顶级节点(Workflow、Sheets、Tasks)的平级展示,结构如下:
-Workflow - 员工入职流程 -Sheets - 入职申请表 - 转正申请表 -Tasks - 填写基本信息 - 部门审核 - 提交转正申请 - 经理审批
只需要修改构建逻辑,把三个节点都作为根的子节点,并且可以隐藏根节点:
// JavaFX版本的平级结构构建方法 public static TreeItem<String> buildFlatTree(Workflow workflow) { TreeItem<String> hiddenRoot = new TreeItem<>("Root"); // 隐藏的根节点 hiddenRoot.setExpanded(true); // Workflow分支 TreeItem<String> workflowNode = new TreeItem<>("Workflow"); workflowNode.getChildren().add(new TreeItem<>(workflow.getName())); hiddenRoot.getChildren().add(workflowNode); // Sheets分支 TreeItem<String> sheetsNode = new TreeItem<>("Sheets"); for (Sheet sheet : workflow.getSheets()) { sheetsNode.getChildren().add(new TreeItem<>(sheet.getName())); } hiddenRoot.getChildren().add(sheetsNode); // Tasks分支 TreeItem<String> tasksNode = new TreeItem<>("Tasks"); for (Sheet sheet : workflow.getSheets()) { for (Task task : sheet.getTasks()) { tasksNode.getChildren().add(new TreeItem<>(task.getName())); } } hiddenRoot.getChildren().add(tasksNode); return hiddenRoot; }
使用时隐藏根节点:
TreeItem<String> root = WorkflowTreeBuilder.buildFlatTree(workflow); TreeView<String> treeView = new TreeView<>(root); treeView.setShowRoot(false); // 隐藏根节点,只显示三个顶级分支
Swing版本的思路(如果用JTree)
核心逻辑和JavaFX完全一致,只是把TreeItem换成DefaultMutableTreeNode,示例代码如下:
import javax.swing.tree.DefaultMutableTreeNode; import java.util.List; public class WorkflowJTreeBuilder { public static DefaultMutableTreeNode buildNestedJTree(Workflow workflow) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("Workflow"); // 添加Workflow名称节点 root.add(new DefaultMutableTreeNode(workflow.getName())); // Sheets节点 DefaultMutableTreeNode sheetsNode = new DefaultMutableTreeNode("Sheets"); root.add(sheetsNode); // 遍历Sheet和Task for (Sheet sheet : workflow.getSheets()) { DefaultMutableTreeNode sheetNode = new DefaultMutableTreeNode(sheet.getName()); sheetsNode.add(sheetNode); DefaultMutableTreeNode tasksNode = new DefaultMutableTreeNode("Tasks"); sheetNode.add(tasksNode); for (Task task : sheet.getTasks()) { tasksNode.add(new DefaultMutableTreeNode(task.getName())); } } return root; } }
最后提醒你:如果需要给节点绑定原始领域对象(比如点击节点时获取对应的Workflow/Sheet/Task实例),可以在TreeItem/DefaultMutableTreeNode中存储对象本身,然后通过自定义CellFactory来渲染显示名称,这样后续的交互逻辑会更灵活。
内容的提问来源于stack exchange,提问作者drstonecodez
相关产品推荐
相关产品推荐

