001/* 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.sdm.spa.gui; 031 032import java.awt.event.WindowAdapter; 033import java.awt.event.WindowEvent; 034import java.io.IOException; 035import java.util.Enumeration; 036import java.util.Vector; 037 038import javax.swing.JEditorPane; 039import javax.swing.JFrame; 040import javax.swing.JPanel; 041import javax.swing.JScrollPane; 042import javax.swing.JSplitPane; 043import javax.swing.JTree; 044import javax.swing.event.TreeModelEvent; 045import javax.swing.event.TreeModelListener; 046import javax.swing.tree.TreePath; 047import javax.xml.parsers.DocumentBuilder; 048import javax.xml.parsers.DocumentBuilderFactory; 049import javax.xml.parsers.ParserConfigurationException; 050 051import org.w3c.dom.Document; 052import org.xml.sax.SAXException; 053import org.xml.sax.SAXParseException; 054 055public class XMLUIP extends JPanel { 056 // Global value so it can be ref'd by the tree-adapter 057 static Document document; 058 059 public XMLUIP() { 060 // Set up the tree 061 JTree tree = new JTree(new DomToTreeModelAdapter()); 062 System.out.println("checkpoint15\n"); 063 // Build left-side view 064 JScrollPane treeView = new JScrollPane(tree); 065 System.out.println("checkpoint16\n"); 066 // Build right-side view 067 JEditorPane htmlPane = new JEditorPane("text/html", ""); 068 htmlPane.setEditable(false); 069 JScrollPane htmlView = new JScrollPane(htmlPane); 070 // Build split-pane view 071 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, 072 treeView, htmlView); 073 // splitPane.setContinuousLayout( true ); 074 // Add GUI components 075 // setLayout(new BorderLayout()); 076 add("Center", splitPane); 077 } // constructor 078 079 public static void makeTree(String filename) { 080 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 081 // factory.setValidating(true); 082 // factory.setNamespaceAware(true); 083 try { 084 DocumentBuilder builder = factory.newDocumentBuilder(); 085 document = builder.parse("src/org/sdm/spa/gui/slideSample01.xml"); 086 // makeFrame(); 087 final XMLUIP echoPanel = new XMLUIP(); 088 } catch (SAXParseException spe) { 089 // Error generated by the parser 090 System.out.println("\n** Parsing error" + ", line " 091 + spe.getLineNumber() + ", uri " + spe.getSystemId()); 092 System.out.println(" " + spe.getMessage()); 093 094 // Use the contained exception, if any 095 Exception x = spe; 096 if (spe.getException() != null) 097 x = spe.getException(); 098 x.printStackTrace(); 099 100 } catch (SAXException sxe) { 101 // Error generated during parsing) 102 Exception x = sxe; 103 if (sxe.getException() != null) 104 x = sxe.getException(); 105 x.printStackTrace(); 106 107 } catch (ParserConfigurationException pce) { 108 // Parser with specified options can't be built 109 pce.printStackTrace(); 110 111 } catch (IOException ioe) { 112 // I/O error 113 ioe.printStackTrace(); 114 } 115 }// makeTree 116 117 public static void main(String argv[]) { 118 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 119 // factory.setValidating(true); 120 // factory.setNamespaceAware(true); 121 try { 122 DocumentBuilder builder = factory.newDocumentBuilder(); 123 document = builder.parse("src/org/sdm/spa/gui/slideSample01.xml"); 124 makeFrame(); 125 126 } catch (SAXParseException spe) { 127 // Error generated by the parser 128 System.out.println("\n** Parsing error" + ", line " 129 + spe.getLineNumber() + ", uri " + spe.getSystemId()); 130 System.out.println(" " + spe.getMessage()); 131 132 // Use the contained exception, if any 133 Exception x = spe; 134 if (spe.getException() != null) 135 x = spe.getException(); 136 x.printStackTrace(); 137 138 } catch (SAXException sxe) { 139 // Error generated during parsing) 140 Exception x = sxe; 141 if (sxe.getException() != null) 142 x = sxe.getException(); 143 x.printStackTrace(); 144 145 } catch (ParserConfigurationException pce) { 146 // Parser with specified options can't be built 147 pce.printStackTrace(); 148 149 } catch (IOException ioe) { 150 // I/O error 151 ioe.printStackTrace(); 152 } 153 } // main 154 155 public static void makeFrame() { 156 // Set up a GUI framework 157 JFrame frame = new JFrame("DOM Echo"); 158 frame.addWindowListener(new WindowAdapter() { 159 public void windowClosing(WindowEvent e) { 160 System.exit(0); 161 } 162 }); 163 // Set up the tree, the views, and display it all 164 final XMLUIP echoPanel = new XMLUIP(); 165 frame.getContentPane().add("Center", echoPanel); 166 frame.pack(); 167 frame.setSize(600, 400); 168 frame.setVisible(true); 169 } // makeFrame 170 171 // An array of names for DOM node-types 172 // (Array indexes = nodeType() values.) 173 static final String[] typeName = { "none", "Element", "Attr", "Text", 174 "CDATA", "EntityRef", "Entity", "ProcInstr", "Comment", "Document", 175 "DocType", "DocFragment", "Notation", }; 176 177 // This class wraps a DOM node and returns the text we want to 178 // display in the tree. It also returns children, index values, 179 // and child counts. 180 public class AdapterNode { 181 org.w3c.dom.Node domNode; 182 183 // Construct an Adapter node from a DOM node 184 public AdapterNode(org.w3c.dom.Node node) { 185 domNode = node; 186 } 187 188 // Return a string that identifies this node in the tree 189 public String toString() { 190 String s = typeName[domNode.getNodeType()]; 191 String nodeName = domNode.getNodeName(); 192 if (!nodeName.startsWith("#")) { 193 s += ": " + nodeName; 194 } 195 if (domNode.getNodeValue() != null) { 196 if (s.startsWith("ProcInstr")) 197 s += ", "; 198 else 199 s += ": "; 200 // Trim the value to get rid of NL's at the front 201 String t = domNode.getNodeValue().trim(); 202 int x = t.indexOf("\n"); 203 if (x >= 0) 204 t = t.substring(0, x); 205 s += t; 206 } 207 return s; 208 } 209 210 /* 211 * Return children, index, and count values 212 */ 213 public int index(AdapterNode child) { 214 // System.err.println("Looking for index of " + child); 215 int count = childCount(); 216 for (int i = 0; i < count; i++) { 217 AdapterNode n = this.child(i); 218 if (child.domNode == n.domNode) 219 return i; 220 } 221 return -1; // Should never get here. 222 } 223 224 public AdapterNode child(int searchIndex) { 225 // Note: JTree index is zero-based. 226 org.w3c.dom.Node node = domNode.getChildNodes().item(searchIndex); 227 return new AdapterNode(node); 228 } 229 230 public int childCount() { 231 return domNode.getChildNodes().getLength(); 232 } 233 } 234 235 // This adapter converts the current Document (a DOM) into 236 // a JTree model. 237 public class DomToTreeModelAdapter implements javax.swing.tree.TreeModel { 238 // Basic TreeModel operations 239 public Object getRoot() { 240 // System.err.println("Returning root: " +document); 241 return new AdapterNode(document); 242 } 243 244 public boolean isLeaf(Object aNode) { 245 // Determines whether the icon shows up to the left. 246 // Return true for any node with no children 247 AdapterNode node = (AdapterNode) aNode; 248 if (node.childCount() > 0) 249 return false; 250 return true; 251 } 252 253 public int getChildCount(Object parent) { 254 AdapterNode node = (AdapterNode) parent; 255 return node.childCount(); 256 } 257 258 public Object getChild(Object parent, int index) { 259 AdapterNode node = (AdapterNode) parent; 260 return node.child(index); 261 } 262 263 public int getIndexOfChild(Object parent, Object child) { 264 AdapterNode node = (AdapterNode) parent; 265 return node.index((AdapterNode) child); 266 } 267 268 public void valueForPathChanged(TreePath path, Object newValue) { 269 // Null. We won't be making changes in the GUI 270 // If we did, we would ensure the new value was really new, 271 // adjust the model, and then fire a TreeNodesChanged event. 272 } 273 274 /* 275 * Use these methods to add and remove event listeners. (Needed to 276 * satisfy TreeModel interface, but not used.) 277 */ 278 private Vector listenerList = new Vector(); 279 280 public void addTreeModelListener(TreeModelListener listener) { 281 if (listener != null && !listenerList.contains(listener)) { 282 listenerList.addElement(listener); 283 } 284 } 285 286 public void removeTreeModelListener(TreeModelListener listener) { 287 if (listener != null) { 288 listenerList.removeElement(listener); 289 } 290 } 291 292 /* 293 * Invoke these methods to inform listeners of changes. (Not needed for 294 * this example.) Methods taken from TreeModelSupport class described at 295 * http://java.sun.com/products/jfc/tsc/articles/jtree/index.html That 296 * architecture (produced by Tom Santos and Steve Wilson) is more 297 * elegant. I just hacked 'em in here so they are immediately at hand. 298 */ 299 public void fireTreeNodesChanged(TreeModelEvent e) { 300 Enumeration listeners = listenerList.elements(); 301 while (listeners.hasMoreElements()) { 302 TreeModelListener listener = (TreeModelListener) listeners 303 .nextElement(); 304 listener.treeNodesChanged(e); 305 } 306 } 307 308 public void fireTreeNodesInserted(TreeModelEvent e) { 309 Enumeration listeners = listenerList.elements(); 310 while (listeners.hasMoreElements()) { 311 TreeModelListener listener = (TreeModelListener) listeners 312 .nextElement(); 313 listener.treeNodesInserted(e); 314 } 315 } 316 317 public void fireTreeNodesRemoved(TreeModelEvent e) { 318 Enumeration listeners = listenerList.elements(); 319 while (listeners.hasMoreElements()) { 320 TreeModelListener listener = (TreeModelListener) listeners 321 .nextElement(); 322 listener.treeNodesRemoved(e); 323 } 324 } 325 326 public void fireTreeStructureChanged(TreeModelEvent e) { 327 Enumeration listeners = listenerList.elements(); 328 while (listeners.hasMoreElements()) { 329 TreeModelListener listener = (TreeModelListener) listeners 330 .nextElement(); 331 listener.treeStructureChanged(e); 332 } 333 } 334 } 335} // XMLUIP.java