我正在尝试解析以下XML文件,并使用自定义图标创建基于它的JTree。
<OBJECTS>
<WINDOW NAME = "WINDOW 01" URL = "URL 01">
<PAGE NAME = "PAGE 01" URL = "PAGE URL 01">
</PAGE>
</WINDOW>
</OBJECTS>
用户定义的节点类如下所示:
public class DataNode extends DefaultMutableTreeNode {
private static final long serialVersionUID = 1L;
public String ObjectType, ObjectName, URL, ElementType;
public DefaultMutableTreeNode node;
public DataNode(DefaultMutableTreeNode node, Element element) {
this.node = node;
this.ObjectType = element.getTagName();
this.ObjectName = element.getAttribute("NAME");
this.URL = element.getAttribute("URL");
this.ElementType = element.getAttribute("TYPE");
}
public DataNode(Element element) {
this.node = new DefaultMutableTreeNode("OBJECT");
this.ObjectType = element.getTagName();
this.ObjectName = "Object List";
this.URL = "";
this.ElementType = "";
}
@Override
public String toString() {
return this.ObjectName;
}
}
这是主要课程:
public class MyOwn {
private JFrame contentsFrame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyOwn window = new MyOwn();
window.contentsFrame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MyOwn() {
contentsFrame = new JFrame();
contentsFrame.setTitle("My JTree");
contentsFrame.setBounds(100, 100, 549, 738);
contentsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTree objectListTree = new JTree(convertXMLtoTree("G:/Collection.xml"));
objectListTree.setAlignmentY(Component.TOP_ALIGNMENT);
objectListTree.setAlignmentX(Component.LEFT_ALIGNMENT);
contentsFrame.getContentPane().add(new JScrollPane(objectListTree));
}
private DefaultMutableTreeNode convertXMLtoTree(String Path) {
NodeList nWindow, nPage;
DefaultMutableTreeNode dRoot, dWindow, dPage;
DataNode xRoot, xWindow, xPage;
try {
File fXmlFile = new File(Path);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
xRoot = new DataNode(doc.getDocumentElement());
dRoot = new DefaultMutableTreeNode(xRoot);
nWindow = doc.getDocumentElement().getElementsByTagName("WINDOW");
for (int i = 0; i < nWindow.getLength(); i++) {
dWindow = new DefaultMutableTreeNode(((Element)(nWindow.item(i))).getAttribute("NAME"));
xWindow = new DataNode(dWindow, (Element)(nWindow.item(i)));
dRoot.add(xWindow);
nPage = ((Element)(nWindow.item(i))).getElementsByTagName("PAGE");
for (int j = 0; j < nPage.getLength(); j++) {
dPage = new DefaultMutableTreeNode(((Element)(nPage.item(j))).getAttribute("NAME"));
xPage = new DataNode(dPage, (Element)(nPage.item(j)));
xWindow.add(xPage);
}
}
return dRoot;
} catch (Exception e) {
return null;
}
}
}
渲染器类如下所示:(突出显示NullPointerException的行)
class MyRenderer extends DefaultTreeCellRenderer {
private static final long serialVersionUID = 1L;
public MyRenderer() { }
public String toString() {
return "NODE NAME";
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus)
{
ImageIcon ObjectsIcon = createImageIcon("images/Element.JPG");
ImageIcon WindowIcon = createImageIcon("images/fig7.jpg");
ImageIcon PageIcon = createImageIcon("images/message_icon.gif");
ImageIcon UnknownIcon = createImageIcon("images/phone_icon.gif");
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
switch (ObjectType(value)) {
case 1: setIcon(ObjectsIcon);
break;
case 2: setIcon(WindowIcon);
break;
case 3: setIcon(PageIcon);
break;
case 0: setIcon(UnknownIcon);
break;
}
return this;
}
protected static ImageIcon createImageIcon(String path) {
java.net.URL imgURL = MyOwn.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
private int ObjectType(Object value) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
DataNode nodeInfo = (DataNode) node.getUserObject(); //This is where the NullPointerException occurs
String title = nodeInfo.ObjectType;
if (title.equalsIgnoreCase("OBJECT"))
return 1;
else if (title.equalsIgnoreCase("WINDOW"))
return 2;
else if (title.equalsIgnoreCase("PAGE"))
return 3;
else
return 0;
}
}
请告诉我为什么nodeInfo对象为null?谢谢你的帮助...
答案 0 :(得分:2)
节点对象为null
,因为您没有为自定义DefaultMutableTreeNode
DataNode
设置用户对象。鉴于您希望匹配可以使用的节点文本:
public DataNode(DefaultMutableTreeNode node, Element element) {
super(element.getTagName());
...
}
然后,在MyRenderer
:
if (value instanceof DataNode) { // added check for class type
String title = (String) node.getUserObject();
...
另外,在DefaultMutableTreeNode
中使用DataNode
作为类成员变量是不必要的。它已经是 DefaultMutableTreeNode
,并且可以使用超类中的继承方法处理任何可能的节点操作。