【Java开源代码栏目提醒】:网学会员在Java开源代码频道为大家收集整理了XTree.java提供大家参考,希望对大家有所帮助!
package ch6.xml;
import java.io.*;
import javax.
xml.parsers.*;
import javax.swing.*;
import javax.swing.tree.*;
import org.w3c.dom.*;
public class XTree extends JTree {
/**
* 这个成员变量储存TreeNode对象用于存储JTree的模型。
* DefaultMutableTreeNode类是在javax.swing.tree中被定义的 默认提供了MutableTreeNode接口的一个实现。
*/
private DefaultMutableTreeNode treeNode;
/**
* 这三个成员变量是JAXP的一部分,用来分析XML文本并转化成DOM(Document Object Model) 对象。
*/
private DocumentBuilderFactory dbf;
private DocumentBuilder db;
private Document doc;
/**
* 这个构造函数通过使用传送到构造器中的XML文本创建一个XTree对象
*
* @参数 text是一个XML格式的XML文本
* @异常 ParserConfigurationException 如果构造函数非正常的设置分析器,就会抛出异常
*/
public XTree(String text) throws ParserConfigurationException
{
super();
// 设置Tree渲染的基本属性
getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
setShowsRootHandles(true);
setEditable(true); // 允许树可以编辑
// 通过初始化对象的DOM来分析对象
dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
db = dbf.newDocumentBuilder();
// 采用DOM根节点并且把它转化成JTree的树模型
treeNode = createTreeNode(parseXml(text));
setModel(new DefaultTreeModel(treeNode));
}
/**
* 这个方法采用一个DOM 节点,然后在子节点中递归直到所有的接点都被添加到DefaultMutableTreeNode中。
* 这是一个递归方法,为了找到根节点下的每一个子节点,它每次都要调用自己。
* JTree然后就可以使用DefaultMutableTreeNode对象了,因为它已经是树型了。
*
* @参数 root org.w3c.Node.Node
* @返回值 返回一个基于根节点DefaultMutableTreeNode对象
*/
private DefaultMutableTreeNode createTreeNode(Node root) {
DefaultMutableTreeNode treeNode = null;
String type, name, value;
NamedNodeMap attribs;
Node attribNode;
// 从根节点中取得数据
type = getNodeType(root);
name = root.getNodeName();
value = root.getNodeValue();
treeNode = new DefaultMutableTreeNode(
root.getNodeType() == Node.TEXT_NODE ? value : name);
// 显示属性
attribs = root.getAttributes();
if (attribs != null) {
for (int i = 0; i < attribs.getLength(); i++) {
attribNode = attribs.item(i);
name = attribNode.getNodeName().trim();
value = attribNode.getNodeValue().trim();
if (value != null) {
if (value.length() > 0) {
treeNode.add(new DefaultMutableTreeNode("[Attribute] --> " + name
+ "=\"" + value + "\""));
}
}
}
}
// 如果存在子节点,递归
if (root.hasChildNodes()) {
NodeList children;
int numChildren;
Node node;
String data;
children = root.getChildNodes();
// 如果子节点非空的话,只递归
if (children != null) {
numChildren = children.getLength();
for (int i = 0; i < numChildren; i++) {
node = children.item(i);
if (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
treeNode.add(createTreeNode(node));
}
file: // end if( node.getNodeType() == Node.ELEMENT_NODE )
data = node.getNodeValue();
if (data != null) {
data = data.trim();
if (!data.equals("\n") && !data.equals("\r\n")
&& data.length() > 0) {
treeNode.add(createTreeNode(node));
}
}
}
}
}
}
return treeNode;
}
/**
* 这个方法,被createTreeNode()用来联系一个字符串和某一种类型的节点。
*
* @参数 node org.w3c.Node.Node
* @返回值 返回显示节点类的字符串
*/
private String getNodeType(Node node) {
String type;
switch (node.getNodeType()) {
case Node.ELEMENT_NODE: {
type = "Element";
break;
}
case Node.ATTRIBUTE_NODE: {
type = "Attribute";
break;
}
case Node.TEXT_NODE: {
type = "Text";
break;
}
case Nod