Plz help...I'm really stuck
Hi,
I wnat to convert an XML file into a JTree, but I also want to be able to make changes to the tree structure. I've been working on this all week and I have gotten nowhere. Any help would be great.
// W3C DOM classes
import org.w3c.dom.*;
// JAXP's classes for DOM I/O
import javax.xml.parsers.*;
// Standard Java classes
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.text.*;
/**
*/
publicclass XmlEditorextends JFrameimplements ActionListener
{
// This is the XTree object which displays the XML in a JTree
private XTreexTree;
// This is the textArea object that will display the raw XML text
private JTextAreatextArea;
// One JScrollPane is the container for the JTree, the other is for the textArea
private JScrollPane jScroll, jScrollRt;
// This JSplitPane is the container for the two JScrollPanes
private JSplitPanesplitPane;
// This JButton handles the tree Refresh feature
private JButtonrefreshButton, addButton, removeButton, clearButton;
private JLabel lbl;
// This Listener allows the frame's close button to work properly
private WindowListenerwinClosing;
privateint newNodeSuffix = 1;
// Menu Objects
privateJMenuBarmenuBar;
privateJMenufileMenu;
privateJMenuItemnewItem, openItem, saveItem, exitItem;
// This JDialog object will be used to allow the user to cancel an exit command
private JDialogverifyDialog;
// These JLabel objects will be used to display the error messages
private JLabelquestion;
// These JButtons are used with the verifyDialog object
private JButtonokButton, cancelButton;
// These two constants set the width and height of the frame
privatestaticfinalint FRAME_WIDTH = 600;
privatestaticfinalint FRAME_HEIGHT = 450;
/**
* This constructor passes the graphical construction off to the overloaded constructor
* and then handles the processing of the XML text
*/
public XmlEditor( String title, ArrayList xmlText )throws ParserConfigurationException
{
this( title );
textArea.setText( ( String )xmlText.get( 0 ) +"\n" );
for (int i = 1; i < xmlText.size(); i++ )
textArea.append( ( String )xmlText.get( i ) +"\n" );
try
{
xTree.refresh( textArea.getText() );
}
catch( Exception ex )
{
String message = ex.getMessage();
System.out.println( message );
}//end try/catch
}//end XmlEditor( String title, String xml )
/**
* This constructor builds a frame containing a JSplitPane, which in turn contains two JScrollPanes.
* One of the panes contains an XTree object and the other contains a JTextArea object.
*/
public XmlEditor( String title )throws ParserConfigurationException
{
// This builds the JFrame portion of the object
super( title );
Toolkittoolkit;
Dimensiondim, minimumSize;
intscreenHeight, screenWidth;
// Initialize basic layout properties
setBackground( Color.lightGray );
getContentPane().setLayout(new BorderLayout() );
// Set the frame's display to be WIDTH x HEIGHT in the middle of the screen
toolkit = Toolkit.getDefaultToolkit();
dim = toolkit.getScreenSize();
screenHeight = dim.height;
screenWidth = dim.width;
setBounds( (screenWidth-FRAME_WIDTH)/2, (screenHeight-FRAME_HEIGHT)/2, FRAME_WIDTH, FRAME_HEIGHT );
// Build the Menu
fileMenu =new JMenu("File" );
newItem =new JMenuItem("New" );
newItem.addActionListener(new newMenuHandler() );
openItem =new JMenuItem("Open" );
openItem.addActionListener(new openMenuHandler() );
saveItem =new JMenuItem("Save" );
saveItem.addActionListener(new saveMenuHandler() );
exitItem =new JMenuItem("Exit" );
exitItem.addActionListener(new exitMenuHandler() );
fileMenu.add( newItem );
fileMenu.add( openItem );
fileMenu.add( saveItem );
fileMenu.add( exitItem );
menuBar =new JMenuBar();
menuBar.add( fileMenu );
setJMenuBar( menuBar );
// Build the verify dialog
verifyDialog =new JDialog( this,"Confirm Exit",true );
verifyDialog.setBounds( (screenWidth-200)/2, (screenHeight-100)/2, 200, 100 );
question =new JLabel("Are you sure you want to exit?" );
okButton =new JButton("OK" );
okButton.addActionListener(this );
cancelButton =new JButton("Cancel" );
cancelButton.addActionListener(this );
verifyDialog.getContentPane().setLayout(new FlowLayout() );
verifyDialog.getContentPane().add( question );
verifyDialog.getContentPane().add( okButton );
verifyDialog.getContentPane().add( cancelButton );
verifyDialog.hide();
// Set the Default Close Operation
setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
// Create the refresh button object
refreshButton =new JButton("Refresh" );
refreshButton.setBorder( BorderFactory.createRaisedBevelBorder() );
refreshButton.addActionListener(this );
JPanel p =new JPanel();
addButton =new JButton("Add");
addButton.addActionListener(this);
removeButton =new JButton("Remove");
removeButton.addActionListener(this);
clearButton =new JButton("Clear");
clearButton.addActionListener(this);
p.add(addButton);
p.add(removeButton);
p.add(clearButton);
lbl =new JLabel();
// Add the button to the frame
getContentPane().add( refreshButton, BorderLayout.NORTH );
// Create two JScrollPane objects
jScroll =new JScrollPane();
jScrollRt =new JScrollPane();
// First, create the JTextArea:
// Create the JTextArea and add it to the right hand JScroll
textArea =new JTextArea( 100,150 );
jScrollRt.getViewport().add( textArea );
// Next, create the XTree
xTree =new XTree();
xTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
xTree.setShowsRootHandles(true );
// A more advanced version of this tool would allow the JTree to be editable
xTree.setEditable(true );
// Wrap the JTree in a JScroll so that we can scroll it in the JSplitPane.
jScroll.getViewport().add( xTree );
///p2.add(xTree);
///jScroll.add(p2);
// Create the JSplitPane and add the two JScroll objects
splitPane =new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, jScroll, jScrollRt );
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(200);
// Provide minimum sizes for the two components in the split pane
minimumSize =new Dimension(200, 150);
jScroll.setMinimumSize( minimumSize );
jScrollRt.setMinimumSize( minimumSize );
// Provide a preferred size for the split pane
splitPane.setPreferredSize(new Dimension(400, 300) );
p.add(lbl, BorderLayout.SOUTH);
p.add(splitPane);
// Add the split pane to the frame
getContentPane().add( p, BorderLayout.CENTER );
//Put the final touches to the JFrame object
validate();
setVisible(true);
// Add a WindowListener so that we can close the window
winClosing =new WindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
verifyDialog.show();
}
};
addWindowListener(winClosing);
}//end XmlEditor()
/**
* When a user event occurs, this method is called. If the action performed was a click
* of the "Refresh" button, then the XTree object is updated using the current XML text
* contained in the JTextArea
*/
publicvoid actionPerformed( ActionEvent ae )
{
//////////////////////////////treeListener = new MyTreeModelListener();
if ( ae.getActionCommand().equals("Refresh" ) )
{
try
{
xTree.refresh( textArea.getText() );
}
catch( Exception ex )
{
String message = ex.getMessage();
ex.printStackTrace();
}//end try/catch
}
elseif ( ae.getActionCommand().equals("OK" ) )
{
exit();
}
elseif ( ae.getActionCommand().equals("Cancel" ) )
{
verifyDialog.hide();
}//end if/else if
elseif (ae.getSource() == addButton){
/// treePanel.addObject("New Node " + newNodeSuffix++);
xTree.addObject("New Node " + newNodeSuffix++);
//treeListener.treeNodesChanged();
System.out.println("Add node");
}
elseif (ae.getSource() == removeButton){
/// treePanel.removeCurrentNode();
xTree.removeCurrentNode();
System.out.println("Remove node");
}
elseif (ae.getSource() == clearButton){
/// treePanel.clear();
xTree.clear();
System.out.println("clear tree");
}
elseif (ae.getSource() == refreshButton){
System.out.println("refresh jtree");
//refresh();
}
}//end actionPerformed()
// Program execution begins here. An XML file (*.xml) must be passed into the method
publicstaticvoid main( String[] args )
{
StringfileName ="";
BufferedReaderreader;
Stringline;
ArrayListxmlText =null;
XmlEditor xmlEditor;
// Build a Document object based on the specified XML file
try
{
if( args.length > 0 )
{
fileName = args[0];
if ( fileName.substring( fileName.indexOf('.' ) ).equals(".xml" ) )
{
reader =new BufferedReader(new FileReader( fileName ) );
xmlText =new ArrayList();
while ( ( line = reader.readLine() ) !=null )
{
xmlText.add( line );
}//end while ( ( line = reader.readLine() ) != null )
// The file will have to be re-read when the Document object is parsed
reader.close();
// Construct the GUI components and pass a reference to the XML root node
xmlEditor =new XmlEditor("XmlEditor 1.0", xmlText );
}
else
{
help();
}//end if ( fileName.substring( fileName.indexOf( '.' ) ).equals( ".xml" ) )
}
else
{
xmlEditor =new XmlEditor("XmlEditor 1.0" );
}//end if( args.length > 0 )
}
catch( FileNotFoundException fnfEx )
{
System.out.println( fileName +" was not found." );
exit();
}
catch( Exception ex )
{
ex.printStackTrace();
exit();
}// end try/catch
}// end main()
// A common source of operating instructions
privatestaticvoid help()
{
System.out.println("\nUsage: java XmlEditor filename.xml" );
System.exit(0);
}//end help()
// A common point of exit
publicstaticvoid exit()
{
System.out.println("\nThank you for using XmlEditor 1.0" );
System.exit(0);
}//end exit()
class newMenuHandlerimplements ActionListener
{
publicvoid actionPerformed( ActionEvent ae )
{
textArea.setText("" );
try
{
// Next, create a new XTree
xTree =new XTree();
xTree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
xTree.setShowsRootHandles(true );
// A more advanced version of this tool would allow the JTree to be editable
xTree.setEditable(false );
}
catch( Exception ex )
{
String message = ex.getMessage();
ex.printStackTrace();
}//end try/catch
}//end actionPerformed()
}//end class newMenuHandler
/* The standard java.io classes were used to create the open file implementation.
A lazier solution would be to use the JtextArea抯 ability to read directly from
a file. The saveMenuHandler() implements a lazy save solution. Either way is fine.
*/
class openMenuHandlerimplements ActionListener
{
JFileChooserjfc;
Containerparent;
intchoice;
openMenuHandler()
{
super();
jfc =new JFileChooser();
jfc.setSize( 400,300 );
jfc.setFileFilter(new XmlFileFilter() );
parent = openItem.getParent();
}//end openMenuHandler()
publicvoid actionPerformed( ActionEvent ae )
{
// Displays the jfc and sets the dialog to 'open'
choice = jfc.showOpenDialog( parent );
if ( choice == JFileChooser.APPROVE_OPTION )
{
StringfileName, line;
BufferedReaderreader;
fileName = jfc.getSelectedFile().getAbsolutePath();
try
{
reader =new BufferedReader(new FileReader( fileName ) );
textArea.setText( reader.readLine() +"\n" );
while ( ( line = reader.readLine() ) !=null )
{
textArea.append( line +"\n" );
}//end while ( ( line = reader.readLine() ) != null )
// The file will have to be re-read when the Document object is parsed
reader.close();
xTree.refresh( textArea.getText() );
}
catch ( Exception ex )
{
String message = ex.getMessage();
ex.printStackTrace();
}//end try/catch
jfc.setCurrentDirectory(new File( fileName ) );
}//end if ( choice == JFileChooser.APPROVE_OPTION )
}//end actionPerformed()
}//end class openMenuHandler
/* This class implements a lazy saving solution. The JtextArea class has a way to
write its contents directly to a file. Under the hood, the JtextArea is still
using the java.io classes, so it is entirely up to you how you choose to
implement this feature.
*/
class saveMenuHandlerimplements ActionListener
{
JFileChooserjfc;
Containerparent;
intchoice;
saveMenuHandler()
{
super();
jfc =new JFileChooser();
jfc.setSize( 400,300 );
jfc.setFileFilter(new XmlFileFilter() );
parent = saveItem.getParent();
}//end saveMenuHandler()
publicvoid actionPerformed( ActionEvent ae )
{
// Displays the jfc and sets the dialog to 'save'
choice = jfc.showSaveDialog( parent );
if ( choice == JFileChooser.APPROVE_OPTION )
{
StringfileName;
FilefObj;
FileWriterwriter;
fileName = jfc.getSelectedFile().getAbsolutePath();
try
{
writer =new FileWriter( fileName );
textArea.write( writer );
// The file will have to be re-read when the Document object is parsed
writer.close();
}
catch ( IOException ioe )
{
ioe.printStackTrace();
}//end try/catch
jfc.setCurrentDirectory(new File( fileName ) );
}//end if ( choice == JFileChooser.APPROVE_OPTION )
}//end actionPerformed()
}//end class saveMenuHandler
class exitMenuHandlerimplements ActionListener
{
publicvoid actionPerformed( ActionEvent ae )
{
verifyDialog.show();
}//end actionPerformed()
}//end class exitMenuHandler
class XmlFileFilterextends javax.swing.filechooser.FileFilter
{
publicboolean accept( File fobj )
{
if ( fobj.isDirectory() )
returntrue;
else
return fobj.getName().endsWith(".xml" );
}//end accept()
public String getDescription()
{
return"*.xml";
}//end getDescription()
}//end class XmlFileFilter
}//end class XmlEditor
===================================================
// W3C DOM classes
import org.w3c.dom.*;
// JAXP's classes for DOM I/O
import javax.xml.parsers.*;
// Standard Java classes
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
/**
* Description: The XTree class is an extension of the javax.swing.JTree class.
* It behaves in every way like a JTree component, the difference is that additional
* methods have been provided to facilitate the parsing of an XML document into a
* DOM object and translating that DOM object into a viewable JTree structure.
*
*/
publicclass XTreeextends JTree
{
/**
* This member stores the TreeNode object used to create the model for the JTree.
* The DefaultMutableTreeNode class is defined in the javax.swing.tree package
* and provides a default implementation of the MutableTreeNode interface.
*/
privateDefaultMutableTreeNodetreeNode;
/**
* These three members are a part of the JAXP API and are used to parse the XML
* text into a DOM object (of type Document).
*/
privateDocumentBuilderFactory dbf;
privateDocumentBuilder db;
privateDocumentdoc;
///////
// DefaultMutableTreeNode rootNode;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
DefaultTreeModel treeModel;
JTree tree;
XmlEditor treePanel;
/* protected DefaultTreeModel treeMod;
protected JTree tree;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
*/
/**
* This constructor builds an XTree object using the XML text
* passed in through the constructor.
*
* @param text A String of XML formatted text
*
* @exception ParserConfigurationException This exception is potentially thrown if
* the constructor configures the parser improperly. It won't.
*/
public XTree( String text )throws ParserConfigurationException
{
this();
refresh( text );
}//end XTree( String text )
/**
* This constructor builds the generic portion of the XTree object that is true for
* any XTree object. It includes a default tree model
*
* @exception ParserConfigurationException This exception is potentially thrown if
* the constructor configures the parser improperly. It won't.
*/
public XTree()throws ParserConfigurationException
{
// Initialize the superclass portion of the object
super();
// Set basic properties for the Tree rendering
/*getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION );
setShowsRootHandles( true );
setEditable( false ); // A more advanced version of this tool would allow the Tree to be editable
*/
treeNode =new DefaultMutableTreeNode("Root Node");
treeModel =new DefaultTreeModel(treeNode);
treeModel.addTreeModelListener(new MyTreeModelListener());
//// tree = new JTree(treeModel);
setEditable(true);
getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
setShowsRootHandles(true);
/*
treeNode = new DefaultMutableTreeNode("Root Node");
treeModel = new DefaultTreeModel(treeNode);
treeModel.addTreeModelListener(new MyTreeModelListener());
tree = new JTree(treeModel);
tree.setEditable(true);
tree.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);
*/
///JScrollPane scrollPane = new JScrollPane(tree);
///add(scrollPane);
////////////////////
// Begin by initializing the object's DOM parsing objects
dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false );
db = dbf.newDocumentBuilder();
// Take the DOM root node and convert it to a Tree model for the JTree
// setModel( buildWelcomeTree() );
populateTree();
}//end XTree()
/**
* This method takes the XML text string passed to it, parses the XML and
* constructs the a DefaultTreeModel that can then be used to construct the
* graphical tree structure from that data
*/
private DefaultTreeModel buildTree( String text )
{
DefaultMutableTreeNodetreeNode;
Node newNode;
// Take the DOM root node and convert it to a Tree model for the JTree
newNode = parseXml( text );
if ( newNode !=null )
{
treeNode = createTreeNode( newNode );
returnnew DefaultTreeModel( treeNode );
}
else
returnnull;
}//end buildTree()
//public void populateTree(XmlEditor treePanel) {
publicvoid populateTree(){
String p1Name =new String("Parent 1");
String p2Name =new String("Parent 2");
String c1Name =new String("Child 1");
String c2Name =new String("Child 2");
DefaultMutableTreeNode p1, p2;
p1 = addObject(null, p1Name);
p2 = addObject(null, p2Name);
addObject(p1, c1Name);
addObject(p1, c2Name);
addObject(p2, c1Name);
addObject(p2, c2Name);
}
/**
* This method builds a default DefaultTreeModel that can then be used to construct
* the graphical tree structure from that data
*/
private DefaultTreeModel buildWelcomeTree()
{
DefaultMutableTreeNoderoot;
DefaultMutableTreeNode instructions, openingDoc, editingDoc, savingDoc;
DefaultMutableTreeNodeopeningDocText, editingDocText, savingDocText;
DefaultMutableTreeNodedevelopment, addingFeatures, contactingKyle;
root =new DefaultMutableTreeNode("Welcome to XML View 1.0" );
instructions =new DefaultMutableTreeNode("Instructions" );
openingDoc =new DefaultMutableTreeNode("Opening XML Documents" );
openingDocText =new DefaultMutableTreeNode("When invoking the XmlEditor from the command-line, you must specify the filename." );
editingDoc =new DefaultMutableTreeNode("Editing an XML Document" );
editingDocText =new DefaultMutableTreeNode("XML text in the right hand frame can be edited directly. The \"refresh\" button will rebuild the JTree in the left frame." );
savingDoc =new DefaultMutableTreeNode("Saving an XML Document" );
savingDocText =new DefaultMutableTreeNode("This iteration of the XmlEditor does not provide the ability to save your document. That will come with the next article." );
root.add( instructions );
instructions.add( openingDoc );
instructions.add( editingDoc );
openingDoc.add( openingDocText );
editingDoc.add( editingDocText );
returnnew DefaultTreeModel( root );
}//end buildWelcomeTree()
/**
* This method is public because it will be called by outside classes.
* Calling this method will cause the text in the JTextArea to be read,
* parsed into a Node object, and used to create a DefaultTreeModel
* which is then used to create the graphical tree structure.
*/
publicvoid refresh( String text )
{
/*TreeModeltreeMod;
// Take the DOM root node and convert it to a Tree model for the JTree
treeMod = buildTree( text );
if ( treeMod != null )
setModel( treeMod );
} //end refresh()
*/
////TreeModeltreeMod;
// Take the DOM root node and convert it to a Tree model for the JTree
treeModel = buildTree( text );
if ( treeModel !=null )
setModel( treeModel );
}//end refresh()
/**
* This takes a DOM Node and recurses through the children until each one is added
* to a DefaultMutableTreeNode. The JTree then uses this object as a tree model.
*
* @param root org.w3c.Node.Node
*
* @return Returns a DefaultMutableTreeNode object based on the root Node passed in
*/
private DefaultMutableTreeNode createTreeNode( Node root )
{
DefaultMutableTreeNode treeNode =null;
Stringtype, name, value;
NamedNodeMapattribs;
NodeattribNode;
// Get data from root node
type = getNodeType( root );
name = root.getNodeName();
value = root.getNodeValue();
// Special case for TEXT_NODE
treeNode =new DefaultMutableTreeNode( root.getNodeType() == Node.TEXT_NODE ? value : name );
// Display the attributes if there are any
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 +"\"" ) );
}//end if ( value.length() > 0 )
}//end if ( value != null )
}//end for( int i = 0; i < attribs.getLength(); i++ )
}//end if( attribs != null )
// Recurse children nodes if any exist
if( root.hasChildNodes() )
{
NodeList children;
intnumChildren;
Nodenode;
Stringdata;
children = root.getChildNodes();
// Only recurse if Child Nodes are non-null
if( children !=null )
{
numChildren = children.getLength();
for (int i=0; i < numChildren; i++)
{
node = children.item(i);
if( node !=null )
{
// A special case could be made for each Node type.
if( node.getNodeType() == Node.ELEMENT_NODE )
{
treeNode.add( createTreeNode(node) );
}//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));
}//end if ( !data.equals("\n") && !data.equals("\r\n") && data.length() > 0 )
}//end if( data != null )
}//end if( node != null )
}//end for (int i=0; i < numChildren; i++)
}//end if( children != null )
}//end if( root.hasChildNodes() )
return treeNode;
}//end createTreeNode( Node root )
/**
* This method returns a string representing the type of node passed in.
*
* @param node org.w3c.Node.Node
*
* @return Returns a String representing the node type
*/
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 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 ="?";
break;
}
}// end switch( node.getNodeType() )
return type;
}//end getNodeType()
/**
* This method performs the actual parsing of the XML text
*
* @param text A String representing an XML document
* @return Returns an org.w3c.Node.Node object
*/
private Node parseXml( String xml )
{
ByteArrayInputStreambyteStream;
byteStream =new ByteArrayInputStream( xml.getBytes() );
try
{
doc = db.parse( byteStream );
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
returnnull;
}
return ( Node )doc.getDocumentElement();
}//end parseXml
//////////////////////////////////////////////////////////////////////////////////////////
/** Remove all nodes except the root node. */
publicvoid clear(){
treeNode.removeAllChildren();
treeModel.reload();
}
/** Remove the currently selected node. */
publicvoid removeCurrentNode(){
TreePath currentSelection = tree.getSelectionPath();
if (currentSelection !=null){
DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
(currentSelection.getLastPathComponent());
MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
if (parent !=null){
treeModel.removeNodeFromParent(currentNode);
return;
}
}
// Either there was no selection, or the root was selected.
toolkit.beep();
}
/** Add child to the currently selected node. */
public DefaultMutableTreeNode addObject(Object child){
DefaultMutableTreeNode parentNode =null;
TreePath parentPath = tree.getSelectionPath();
if (parentPath ==null){
parentNode = treeNode;
}else{
parentNode = (DefaultMutableTreeNode)
(parentPath.getLastPathComponent());
}
return addObject(parentNode, child,true);
}
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
Object child){
return addObject(parent, child,false);
}
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
Object child,
boolean shouldBeVisible){
DefaultMutableTreeNode childNode =
new DefaultMutableTreeNode(child);
if (parent ==null){
parent = treeNode;
}
treeModel.insertNodeInto(childNode, parent,
parent.getChildCount());
//Make sure the user can see the lovely new node.
if (shouldBeVisible){
tree.scrollPathToVisible(new TreePath(childNode.getPath()));
}
return childNode;
}
class MyTreeModelListenerimplements TreeModelListener{
publicvoid treeNodesChanged(TreeModelEvent e){
DefaultMutableTreeNode node;
node = (DefaultMutableTreeNode)
(e.getTreePath().getLastPathComponent());
/*
* If the event lists children, then the changed
* node is the child of the node we've already
* gotten. Otherwise, the changed node and the
* specified node are the same.
*/
try{
int index = e.getChildIndices()[0];
node = (DefaultMutableTreeNode)
(node.getChildAt(index));
}catch (NullPointerException exc){}
System.out.println("The user has finished editing the node.");
System.out.println("New value: " + node.getUserObject());
}
publicvoid treeNodesInserted(TreeModelEvent e){
}
publicvoid treeNodesRemoved(TreeModelEvent e){
}
publicvoid treeStructureChanged(TreeModelEvent e){
}
}
///////////////////////////////////////////////////////////////////////////////////////////
}//end class XTree

