I am trying to Parse the below XML file and create an JTree based on it with custom Icons.
<OBJECTS>
<WINDOW NAME = "WINDOW 01" URL = "URL 01">
<PAGE NAME = "PAGE 01" URL = "PAGE URL 01">
</PAGE>
</WINDOW>
</OBJECTS>
The User Defined Node class is as given below:
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;
}
}
This is the main class:
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;
}
}
}
The renderer class is given below: (The line at which the NullPointerException is thrown is highlighted)
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;
}
}
Please let me know why the nodeInfo object is null?? thanks for your help...
The node object is null
as you're not setting the user object for your custom DefaultMutableTreeNode
DataNode
. Given that you want to match the node text you could use:
public DataNode(DefaultMutableTreeNode node, Element element) {
super(element.getTagName());
...
}
Then, in MyRenderer
:
if (value instanceof DataNode) { // added check for class type
String title = (String) node.getUserObject();
...
As an aside, the use of a DefaultMutableTreeNode
as a class member variable in DataNode
is unnecessary. It already is a DefaultMutableTreeNode
and any possible node operations can be handled using the inherited methods from the super class.