/*
* XML2JTree.java
*
* Created on February 27, 2006, 6:26 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package edu.mbl.jif.imaging.meta;
// Import the W3C DOM clas ses
import org.w3c.dom.*;
// We are going to use JAXP's classes for DOM I/O
import javax.xml.parsers.*;
// Import other Java classes
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
Displays XML in a JTree
*/
public class XML2JTree extends JPanel
{
private JTree jTree;
private static JFrame frame;
public static final int FRAME_WIDTH = 540;
public static final int FRAME_HEIGHT = 380;
public XML2JTree( Node root, boolean showDetails )
{
// Take a DOM and convert it to a Tree model for the JTree
DefaultMutableTreeNode top = createTreeNode(root, showDetails );
DefaultTreeModel dtModel = new DefaultTreeModel(top);
// Create our JTree
jTree = new JTree(dtModel);
// We have no tree listener but this looks more natrual
jTree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
jTree.setShowsRootHandles(true);
// If this were editable it would result in too much code
// for this demo.
jTree.setEditable(false);
// Create a new JScrollPane but override one of the methods.
JScrollPane jScroll = new JScrollPane()
{
// This keeps the scrollpane a reasonable size
public Dimension getPreferredSize()
{
return new Dimension( FRAME_WIDTH-20, FRAME_HEIGHT-40 );
}
};
// Wrap the JTree in a JScroll so that we can scroll it in the JSplitPane.
jScroll.getViewport().add(jTree);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add("Center", jScroll);
add("Center", panel);
}
/**
This takes a DOM Node and recurses through the children until each one is
added to a DefaultMutableTreeNode. This can then be used by the JTree as a
tree model. The second parameter can be used to provide more visual detail
for debugging.
*/
protected DefaultMutableTreeNode createTreeNode( Node root, boolean showDetails )
{
DefaultMutableTreeNode dmtNode = null;
String type = getNodeType(root);
String name = root.getNodeName();
String value = root.getNodeValue();
if( showDetails )
{
dmtNode = new DefaultMutableTreeNode("["+type+"] --> "+name+" = "+value);
}
else
{
// Special case for TEXT_NODE, others are similar but not catered for here.
dmtNode = new DefaultMutableTreeNode(
root.getNodeType() == Node.TEXT_NODE ? value : name );
}
// Display the attributes if there are any
NamedNodeMap attribs = root.getAttributes();
if(attribs != null && showDetails )
{
for( int i = 0; i < attribs.getLength(); i++ )
{
Node attNode = attribs.item(i);
String attName = attNode.getNodeName().trim();
String attValue = attNode.getNodeValue().trim();
if(attValue != null)
{
if (attValue.length() > 0)
{
dmtNode.add(new DefaultMutableTreeNode(
"[Attribute] --> "+attName+"=\""+attValue+"\"") );
}
}
}
}
// If there are any children and they are non-null then recurse...
if(root.hasChildNodes())
{
NodeList childNodes = root.getChildNodes();
if(childNodes != null)
{
for (int k=0; k<childNodes.getLength(); k++)
{
Node nd = childNodes.item(k);
if( nd != null )
{
// A special case could be made for each Node type.
if( nd.getNodeType() == Node.ELEMENT_NODE )
{
dmtNode.add(createTreeNode(nd, showDetails));
}
// This is the default
String data = nd.getNodeValue();
if(data != null)
{
data = data.trim();
if(!data.equals("\n") && !data.equals("\r\n") &&
data.length() > 0)
{
dmtNode.add(createTreeNode(nd, showDetails));
}
}
}
}
}
}
return dmtNode;
}
/**
This simple method returns a displayable string given a NodeType
*/
public 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 Node.CDATA_SECTION_NODE:
{
type = "CData section";
break;
}
case Node.ENTITY_REFERENCE_NODE:
{
type = "Entity reference";
break;
}
case Node.ENTITY_NODE:
{
type = "Entity";
break;
}
case Node.PROCESSING_INSTRUCTION_NODE:
{
type = "Processing instruction";
break;
}
case Node.COMMENT_NODE:
{
type = "Comment";
break;
}
case Node.DOCUMENT_NODE:
{
type = "Document";
break;
}
case Node.DOCUMENT_TYPE_NODE:
{
type = "Document type";
break;
}
case Node.DOCUMENT_FRAGMENT_NODE:
{
type = "Document fragment";
break;
}
case Node.NOTATION_NODE:
{
type = "Notation";
break;
}
default:
{
type = "Unknown, contact Sun!";
break;
}
}
return type;
}
/**
A common point of exit...
*/
private static void exit()
{
System.out.println("Graceful exit");
System.exit(0);
}
/**
This main is simply to test this class
*/
public static void main( String[] args )
{
Document doc = null;
// Just check we have the right parameters first.
// if( args.length < 1 )
// {
// System.out.println( "Usage:\tXML2JTree filename.xml" );
// return;
// }
String filename = // args[0];
"C:\\_dev\\__Dev_Current\\XML\\XMLEncoder\\Sample.xml";
boolean showDetails = false;
if( args.length == 2 )
{
// If anything's there override the default
showDetails = Boolean.valueOf(args[1]).booleanValue();
}
// Create a frame to "hold" our class
frame = new JFrame("XML to JTree");
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getScreenSize();
int screenHeight = dim.height;
int screenWidth = dim.width;
// This should display a WIDTH x HEIGHT sized Frame in the middle of the screen
frame.setBounds( (screenWidth-FRAME_WIDTH)/2,
(screenHeight-FRAME_HEIGHT)/2, FRAME_WIDTH, FRAME_HEIGHT );
frame.setBackground(Color.lightGray);
frame.getContentPane().setLayout(new BorderLayout());
// Give our frame an icon when it's minimized.
frame.setIconImage(toolkit.getImage("Wrox.gif"));
// Add a WindowListener so that we can close the window
WindowListener wndCloser = new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
exit();
}
};
frame.addWindowListener(wndCloser);
// ====================================
try
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false); // Not important fro this demo
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(filename);
}
catch( FileNotFoundException fnfEx )
{
// Display a "nice" warning message if the file isn't there.
JOptionPane.showMessageDialog(frame, filename+" was not found",
"Warning", JOptionPane.WARNING_MESSAGE);
System.out.println();
exit();
}
catch( Exception ex )
{
JOptionPane.showMessageDialog(frame, ex.getMessage(), "Exception",
JOptionPane.WARNING_MESSAGE);
ex.printStackTrace();
exit();
}
Node root = (Node)doc.getDocumentElement();
frame.getContentPane().add(new XML2JTree( root, showDetails ),
BorderLayout.CENTER);
frame.validate();
frame.setVisible(true);
}
}