aspose file tools*
The moose likes Java in General and the fly likes XML to DOM to JTree Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "XML to DOM to JTree" Watch "XML to DOM to JTree" New topic
Author

XML to DOM to JTree

varsha rao
Greenhorn

Joined: Mar 06, 2006
Posts: 26
hello everybody,
im developing an application wherein im reading an XML file and converting it to a DOM and displaying the latter as aJTree.
i want to allow the user to add / removenodes from the JTree insuch a way that the changes are incorporated in the DOM and the XML file as well.
Can anybody guide me on how to do this, its really urgent?
regards
varsha
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12769
    
    5
Don't try to do this project in one step. I suggest that you start with a test program to read the XML into a DOM, modify the DOM and write it out. Once you have that working it will be time to add the JTree display and user interaction.
Bill
varsha rao
Greenhorn

Joined: Mar 06, 2006
Posts: 26
@william,
iv already done what uv told, iv coverted my XML file to a Dom and am able to display it, but the prb im getting is while addin. im not able to add a new node to it
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12769
    
    5
Usually when people say they can't modify a DOM it turns out that the modification is being made but they are not writing the modified DOM out correctly. How are you doing the output of the modified DOM?

Bill
varsha rao
Greenhorn

Joined: Mar 06, 2006
Posts: 26
@william
im displaying the modified dom also as a tree, but the problem is its only getting added as a leaf and later when i add another node to this newly added lead its not coming right.
Here is my code-






import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;


import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.File;
import java.io.IOException;

import org.w3c.dom.*;


// Basic GUI components
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;

// GUI components for right-hand side
import javax.swing.*;


// GUI support classes
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.*;


// For creating borders
import javax.swing.border.EmptyBorder;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;

// For creating a TreeModel
import javax.swing.tree.*;
import javax.swing.event.*;
import java.util.*;

public class DomCatEcho extends JPanel implements ActionListener {
// Global value so it can be ref'd by the tree-adapter
static Document document;

boolean compress = true;
static final int windowHeight = 460;
static final int leftWidth = 300;
static final int rightWidth = 340;
static final int windowWidth = leftWidth + rightWidth;
JTree tree;
JMenuBar mBar;
JScrollPane treeView;
//protected DomToTreeModelAdapter treeModel;

public DomCatEcho()
{
// Make a nice border
EmptyBorder eb = new EmptyBorder(5,5,5,5);
BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);
CompoundBorder cb = new CompoundBorder(eb,bb);
this.setBorder(new CompoundBorder(cb,eb));

// treeModel=new DomToTreeModelAdapter(new DefaultMutableTreeNode());
// Set up the tree
tree = new JTree(new DomToTreeModelAdapter() );

// Iterate over the tree and make nodes visible
// (Otherwise, the tree shows up fully collapsed)
//TreePath nodePath = ???;
// tree.expandPath(nodePath);

// Build left-side view
treeView = new JScrollPane(tree);
treeView.setPreferredSize(
new Dimension( leftWidth, windowHeight ));

// Build right-side view
JEditorPane htmlPane = new JEditorPane("text/html","");
htmlPane.setEditable(false);
JScrollPane htmlView = new JScrollPane(htmlPane);
htmlView.setPreferredSize(
new Dimension( rightWidth, windowHeight ));

// Build split-pane view
JSplitPane splitPane =
new JSplitPane( JSplitPane.HORIZONTAL_SPLIT,
treeView,
htmlView );
splitPane.setContinuousLayout( true );
splitPane.setDividerLocation( leftWidth );
splitPane.setPreferredSize(
new Dimension( windowWidth + 10, windowHeight+10 ));

//add menu bar
mBar=new JMenuBar();
JMenu mMenu=new JMenu("ADD NODE");
JMenuItem mItem=new JMenuItem("ADD");
mBar.add(mMenu);
mMenu.add(mItem);
mItem.addActionListener(this);

// Add GUI components
this.setLayout(new BorderLayout());
this.add("Center", splitPane );
this.add(mBar,BorderLayout.NORTH);
} // constructor

public static void main(String argv[])
{
if (argv.length != 1) {
System.err.println("Usage: java DomEcho filename");
System.exit(1);
}

DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();

try {
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse( new File(argv[0]) );

// Use a Transformer for output (just a try)
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
// transformer.transform(source, result);

makeFrame();

} catch (TransformerConfigurationException tce) {
// Error generated by the parser
System.out.println ("\n** Transformer Factory error");
System.out.println(" " + tce.getMessage() );

// Use the contained exception, if any
Throwable x = tce;
if (tce.getException() != null)
x = tce.getException();
x.printStackTrace();

} catch (TransformerException te) {
// Error generated by the parser
System.out.println ("\n** Transformation error");
System.out.println(" " + te.getMessage() );

// Use the contained exception, if any
Throwable x = te;
if (te.getException() != null)
x = te.getException();
x.printStackTrace();

}catch (SAXException sxe) {
// Error generated during parsing)
Exception x = sxe;
if (sxe.getException() != null)
x = sxe.getException();
x.printStackTrace();

} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
pce.printStackTrace();

} catch (IOException ioe) {
// I/O error
ioe.printStackTrace();
}
} // main

public static void makeFrame() {
// Set up a GUI framework
JFrame frame = new JFrame("DOM Echo");
frame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
}
);

// Set up the tree, the views, and display it all
final DomCatEcho echoPanel =
new DomCatEcho();
frame.getContentPane().add("Center", echoPanel );
frame.pack();
Dimension screenSize =
Toolkit.getDefaultToolkit().getScreenSize();
int w = windowWidth + 10;
int h = windowHeight + 10;
frame.setLocation(screenSize.width/3 - w/2,
screenSize.height/2 - h/2);

frame.setSize(w, h);
frame.setVisible(true);
} // makeFrame



public void actionPerformed(ActionEvent ae) {

//Using an option pane teporarily to get the name...
String catName=JOptionPane.showInputDialog("Enter Category Name ");
try {

Element newElement=document.createElement("Sub_category");

//Geting the selected Node
TreePath selPath= tree.getSelectionPath();

AdapterNode selAdapterNode=
(AdapterNode)selPath.getLastPathComponent();


org.w3c.dom.Node selNode=selAdapterNode.getNode();
org.w3c.dom.Node parent=selNode.getParentNode();
newElement.setTextContent(catName);
// System.out.println("Selected Path :"+selPath.toString());
//System.out.println("New TExt content :"+newElement.getTextContent().trim());
parent.appendChild((org.w3c.dom.Node)newElement);
TreePath newNodePath = selPath.pathByAddingChild(newElement);

/*Object[] pathChng={ newNodePath };
Object[] nodeName= { newElement.getTextContent() };

treeModel.fireNodesInserted((Object)parent,pathChng,tree.getSelectionRows(),nodeName);
*/
//treeModel.reload();
tree.setModel(new DomToTreeModelAdapter() );



// Use a Transformer for output (just a try)
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
// transformer.transform(source, result);


// tree.validate();

// tree.repaint();
tree.expandPath(selPath);


}
catch (Exception dex) {
System.out.println("Exception while node adding: "+dex.toString());

}



}


// An array of names for DOM node-types
// (Array indexes = nodeType() values.)
static final String[] typeName = {
"none",
"Element",
"Attr",
"Text",
"CDATA",
"EntityRef",
"Entity",
"ProcInstr",
"Comment",
"Document",
"DocType",
"DocFragment",
"Notation",
};
static final int ELEMENT_TYPE = 1;
// The list of elements to display in the tree
// Could set this with a command-line argument, but
// not much point -- the list of tree elements still
// has to be defined internally.
// Extra credit: Read the list from a file
// Super-extra credit: Process a DTD and build the list.
static String[] treeElementNames = {
"Category_list",
"Category",
"Sub_category",
};
boolean treeElement(String elementName) {
for (int i=0; i<treeElementNames.length; i++) {
if ( elementName.equals(treeElementNames[i]) ) return true;
}
return false;
}

// This class wraps a DOM node and returns the text we want to
// display in the tree. It also returns children, index values,
// and child counts.
public class AdapterNode
{
org.w3c.dom.Node domNode;

// Construct an Adapter node from a DOM node
public AdapterNode(org.w3c.dom.Node node) {
domNode = node;
}

// Return a string that identifies this node in the tree
// *** Refer to table at top of org.w3c.dom.Node ***
public String toString() {
String s=typeName[domNode.getNodeType()];
if(domNode.getNodeName().equals("Category_list")) {
s=domNode.getNodeName();
}
else if(!s.equals("Document")) {
String t =domNode.getTextContent().trim();//
int x = t.indexOf("\n");
if (x >= 0) t = t.substring(0, x);
s=t;
String nodeName = domNode.getNodeName();
}

return s;
}

public org.w3c.dom.Node getNode() {
return domNode;
}
/*
* Return children, index, and count values
*/
public int index(AdapterNode child) {
//System.err.println("Looking for index of " + child);
int count = childCount();
for (int i=0; i<count; i++) {
AdapterNode n = this.child(i);
if (child.domNode == n.domNode) return i;
}
return -1; // Should never get here.
}

public AdapterNode child(int searchIndex) {
//Note: JTree index is zero-based.
org.w3c.dom.Node node =
domNode.getChildNodes().item(searchIndex);
if (compress) {
// Return Nth displayable node
int elementNodeIndex = 0;
for (int i=0; i<domNode.getChildNodes().getLength(); i++) {
node = domNode.getChildNodes().item(i);
if (node.getNodeType() == ELEMENT_TYPE
&& treeElement( node.getNodeName() )
&& elementNodeIndex++ == searchIndex) {
break;
}
}
}
return new AdapterNode(node);
}

public int childCount() {
if (!compress) {
// Indent this
return domNode.getChildNodes().getLength();
}
int count = 0;
for (int i=0; i<domNode.getChildNodes().getLength(); i++) {
org.w3c.dom.Node node = domNode.getChildNodes().item(i);
if (node.getNodeType() == ELEMENT_TYPE
&& treeElement( node.getNodeName() ))
{
// Note:
// Have to check for proper type.
// The DOCTYPE element also has the right name
++count;
}
}
return count;
}
}

// This adapter converts the current Document (a DOM) into
// a JTree model.
public class DomToTreeModelAdapter
implements javax.swing.tree.TreeModel
{

/*public DomToTreeModelAdapter(TreeNode dummyNode) {
//System.err.println("Returning root: " +document);
super(dummyNode);
}*/
// Basic TreeModel operations
public Object getRoot() {
//System.err.println("Returning root: " +document);
return new AdapterNode(document);
}
public boolean isLeaf(Object aNode) {
// Determines whether the icon shows up to the left.
// Return true for any node with no children
AdapterNode node = (AdapterNode) aNode;
if (node.childCount() > 0) return false;
return true;
}
public int getChildCount(Object parent) {
AdapterNode node = (AdapterNode) parent;
return node.childCount();
}
public Object getChild(Object parent, int index) {
AdapterNode node = (AdapterNode) parent;
return node.child(index);
}
public int getIndexOfChild(Object parent, Object child) {
AdapterNode node = (AdapterNode) parent;
return node.index((AdapterNode) child);
}
public void valueForPathChanged(TreePath path, Object newValue) {
// Null. We won't be making changes in the GUI
// If we did, we would ensure the new value was really new,
// adjust the model, and then fire a TreeNodesChanged event.
}

/*
* Use these methods to add and remove event listeners.
* (Needed to satisfy TreeModel interface, but not used.)
*/
private Vector listenerList = new Vector();
public void addTreeModelListener(TreeModelListener listener) {
if ( listener != null
&& ! listenerList.contains( listener ) ) {
listenerList.addElement( listener );
}
}
public void removeTreeModelListener(TreeModelListener listener) {
if ( listener != null ) {
listenerList.removeElement( listener );
}
}


/*
* Invoke these methods to inform listeners of changes.
* (Not needed for this example.)
*/
/* public void fireTreeNodesChanged( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeNodesChanged( e );
}
}
public void fireNodesInserted(Object source, Object[] path, int[]
childIndices, Object[] children) {

fireTreeNodesInserted(source,path,childIndices,children);


}
public void fireTreeNodesRemoved( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeNodesRemoved( e );
}
}
public void fireTreeStructureChanged( TreeModelEvent e ) {
Enumeration listeners = listenerList.elements();
while ( listeners.hasMoreElements() ) {
TreeModelListener listener =
(TreeModelListener) listeners.nextElement();
listener.treeStructureChanged( e );
}
}*/
}
}

------------------------------------------------------------------------
here is the xml file that im parsing
<?xml version='1.0' encoding='utf-8'?>

<Category_list>
<Category>
Entertainment
<Sub_category>
Music
<Sub_category>Hindustani
<Sub_category>Instrumental</Sub_category>
<Sub_category>Vocal</Sub_category>
</Sub_category>
<Sub_category>Carnatic</Sub_category>
<Sub_category>Indipop</Sub_category>
</Sub_category>
<Sub_category>
Movies
<Sub_category>Bollywood</Sub_category>
<Sub_category>Hollywood</Sub_category>
</Sub_category>
</Category>
<Category>
Literature
<Sub_category>
Books
<Sub_category>Fiction</Sub_category>
<Sub_category>Suspense</Sub_category>
<Sub_category>Horror</Sub_category>
</Sub_category>
<Sub_category>
Plays
<Sub_category>Skits</Sub_category>
<Sub_category>Drama</Sub_category>
<Sub_category>Mono Act</Sub_category>
</Sub_category>
</Category>
</Category_list>
[ April 19, 2006: Message edited by: varsha rao ]
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12769
    
    5
My advice continues to be:
Don't try to do this project in one step. I suggest that you start with a test program to read the XML into a DOM, modify the DOM and write it out. Once you have that working it will be time to add the JTree display and user interaction.


Your XML design has bad practices:
"Sub_category" elements appear at (at least) 2 levels in the hierarchy
Text nodes are freely mixed with Elements - for example in:

This is going to be hard to keep straight, I think you need to take another pass at the XML design and then write a simple example that is separate from the GUI design.
Bill
varsha rao
Greenhorn

Joined: Mar 06, 2006
Posts: 26
@william,
thanks, il try to do it ur way and il get back to u soon
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: XML to DOM to JTree