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