如何区分JTree中的Hash与Array节点并转换为指定格式字符串?
解决JTree中Hash/Array节点区分与字符串转换问题
首先,DefaultTreeNode本身没有内置的类型标记字段,但我们完全可以通过扩展或者包装对象的方式来实现节点类型的区分,下面分步骤给你讲清楚怎么做:
1. 给节点添加类型标识:自定义包装类或扩展节点
最简单的方式是创建一个包装类,把你的Hash/Array/String对象和它的类型信息绑定在一起,然后作为DefaultTreeNode的userObject存储。比如:
class NodeWrapper { private Object data; private NodeType type; public enum NodeType { HASH, ARRAY, STRING } public NodeWrapper(Object data, NodeType type) { this.data = data; this.type = type; } // getter方法 public Object getData() { return data; } public NodeType getType() { return type; } // 可选:重写toString,方便JTree显示 @Override public String toString() { return data.toString(); } }
当然你也可以直接继承DefaultTreeNode,给它加个类型属性:
class TypedTreeNode extends DefaultTreeNode { private NodeType type; public enum NodeType { HASH, ARRAY, STRING } public TypedTreeNode(Object userObject, NodeType type) { super(userObject); this.type = type; } public NodeType getType() { return type; } }
2. 构建JTree时绑定类型信息
不管用哪种方式,在创建节点的时候,都要把对应的类型传进去。比如对应你的示例结构:
// 构建Array节点 DefaultTreeNode arrayRoot = new DefaultTreeNode(new NodeWrapper("Array", NodeWrapper.NodeType.ARRAY)); // 构建Hash1节点 DefaultTreeNode hash1 = new DefaultTreeNode(new NodeWrapper("Hash1", NodeWrapper.NodeType.HASH)); hash1.add(new DefaultTreeNode(new NodeWrapper("String1", NodeWrapper.NodeType.STRING))); hash1.add(new DefaultTreeNode(new NodeWrapper("String2", NodeWrapper.NodeType.STRING))); arrayRoot.add(hash1); // 同理构建Hash2和Array1节点... JTree tree = new JTree(arrayRoot);
3. 遍历JTree生成带类型区分的字符串
接下来就是遍历树,根据节点类型生成对应的符号(Array用[ ],Hash用{ },字符串直接输出)。这里可以用递归遍历的方式:
private String treeToString(DefaultTreeNode node) { NodeWrapper wrapper = (NodeWrapper) node.getUserObject(); StringBuilder sb = new StringBuilder(); switch (wrapper.getType()) { case ARRAY: sb.append("["); break; case HASH: sb.append("{"); break; case STRING: // 这里可以加长度判断实现省略效果,比如超过5字符显示Stri... String str = wrapper.getData().toString(); return str.length() > 5 ? "\"" + str.substring(0,4) + "...\"" : "\"" + str + "\""; } // 遍历子节点 Enumeration<?> children = node.children(); boolean first = true; while (children.hasMoreElements()) { if (!first) { sb.append(", "); } first = false; DefaultTreeNode child = (DefaultTreeNode) children.nextElement(); sb.append(treeToString(child)); } // 闭合括号 switch (wrapper.getType()) { case ARRAY: sb.append("]"); break; case HASH: sb.append("}"); break; } return sb.toString(); }
调用这个方法,就能得到你想要的类似[{\"Stri...\", \"Stri...\"}, {\"Stri...\", \"Stri...\", \"Stri...\"}, [\"Stri...\"]]的字符串了。
额外小提示
如果不想自定义类,也可以利用DefaultTreeNode的setUserObject存储一个Map或者自定义数组,把类型和数据一起存进去,但自定义包装类的方式更清晰、更易维护。
内容的提问来源于stack exchange,提问作者Luis
相关产品推荐
相关产品推荐

