KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > util > gui > DOMViewer


1 /*
2
3    Copyright 2000,2002-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.util.gui;
19
20 import java.awt.BorderLayout JavaDoc;
21 import java.awt.Component JavaDoc;
22 import java.awt.FlowLayout JavaDoc;
23 import java.awt.GridLayout JavaDoc;
24 import java.awt.event.ActionEvent JavaDoc;
25 import java.awt.event.ItemEvent JavaDoc;
26 import java.awt.event.ItemListener JavaDoc;
27
28 import java.util.ArrayList JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.ResourceBundle JavaDoc;
34
35 import javax.swing.AbstractAction JavaDoc;
36 import javax.swing.Action JavaDoc;
37 import javax.swing.BorderFactory JavaDoc;
38 import javax.swing.ImageIcon JavaDoc;
39 import javax.swing.JCheckBox JavaDoc;
40 import javax.swing.JFrame JavaDoc;
41 import javax.swing.JPanel JavaDoc;
42 import javax.swing.JScrollPane JavaDoc;
43 import javax.swing.JSplitPane JavaDoc;
44 import javax.swing.JTable JavaDoc;
45 import javax.swing.JTextArea JavaDoc;
46 import javax.swing.JTree JavaDoc;
47 import javax.swing.event.TreeSelectionEvent JavaDoc;
48 import javax.swing.event.TreeSelectionListener JavaDoc;
49 import javax.swing.table.AbstractTableModel JavaDoc;
50 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
51 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
52 import javax.swing.tree.DefaultTreeModel JavaDoc;
53 import javax.swing.tree.MutableTreeNode JavaDoc;
54 import javax.swing.tree.TreeNode JavaDoc;
55
56 import org.apache.batik.util.gui.resource.ActionMap;
57 import org.apache.batik.util.gui.resource.ButtonFactory;
58 import org.apache.batik.util.gui.resource.MissingListenerException;
59 import org.apache.batik.util.gui.resource.ResourceManager;
60 import org.w3c.dom.Document JavaDoc;
61 import org.w3c.dom.Element JavaDoc;
62 import org.w3c.dom.NamedNodeMap JavaDoc;
63 import org.w3c.dom.Node JavaDoc;
64 import org.w3c.dom.css.CSSStyleDeclaration;
65 import org.w3c.dom.css.ViewCSS;
66
67 /**
68  * The components of this class are used to view a DOM tree.
69  *
70  * @author <a HREF="mailto:stephane@hillion.org">Stephane Hillion</a>
71  * @version $Id: DOMViewer.java,v 1.8 2005/02/12 01:48:24 deweese Exp $
72  */

73 public class DOMViewer extends JFrame JavaDoc implements ActionMap {
74     /**
75      * The resource file name
76      */

77     protected final static String JavaDoc RESOURCE =
78     "org.apache.batik.util.gui.resources.DOMViewerMessages";
79
80     /**
81      * The resource bundle
82      */

83     protected static ResourceBundle JavaDoc bundle;
84
85     /**
86      * The resource manager
87      */

88     protected static ResourceManager resources;
89
90     static {
91         bundle = ResourceBundle.getBundle(RESOURCE, Locale.getDefault());
92         resources = new ResourceManager(bundle);
93     }
94
95     /**
96      * The map that contains the listeners
97      */

98     protected Map JavaDoc listeners = new HashMap JavaDoc();
99
100     /**
101      * The panel.
102      */

103     protected Panel JavaDoc panel = new Panel JavaDoc();
104
105     protected boolean showWhitespace = true;
106
107     /**
108      * Creates a new DOMViewer panel.
109      */

110     public DOMViewer() {
111     super(resources.getString("Frame.title"));
112     setSize(resources.getInteger("Frame.width"),
113         resources.getInteger("Frame.height"));
114
115     listeners.put("CloseButtonAction", new CloseButtonAction());
116     
117     getContentPane().add(panel);
118
119         JPanel JavaDoc p = new JPanel JavaDoc(new BorderLayout JavaDoc());
120         
121         JCheckBox JavaDoc cb = new JCheckBox JavaDoc("Show Whitespace Text Nodes");
122         cb.setSelected(showWhitespace);
123         cb.addItemListener(new ItemListener JavaDoc() {
124                 public void itemStateChanged(ItemEvent JavaDoc ie) {
125                     setShowWhitespace
126                         (ie.getStateChange() == ItemEvent.SELECTED);
127                 }
128             });
129
130         p.add(cb, BorderLayout.WEST);
131         
132
133         ButtonFactory bf = new ButtonFactory(bundle, this);
134         p.add(bf.createJButton("CloseButton"), BorderLayout.EAST);
135     getContentPane().add("South", p);
136     }
137
138     public void setShowWhitespace(boolean state) {
139         showWhitespace = state;
140         if (panel.document != null)
141             panel.setDocument(panel.document);
142     }
143
144     /**
145      * Sets the document to display.
146      */

147     public void setDocument(Document JavaDoc doc) {
148     panel.setDocument(doc);
149     }
150
151     /**
152      * Sets the document to display and its ViewCSS.
153      */

154     public void setDocument(Document JavaDoc doc, ViewCSS view) {
155     panel.setDocument(doc, view);
156     }
157
158     /**
159      * Returns the action associated with the given string
160      * or null on error
161      * @param key the key mapped with the action to get
162      * @throws MissingListenerException if the action is not found
163      */

164     public Action JavaDoc getAction(String JavaDoc key) throws MissingListenerException {
165         return (Action JavaDoc)listeners.get(key);
166     }
167
168     /**
169      * The action associated with the 'Close' button of the viewer panel
170      */

171     protected class CloseButtonAction extends AbstractAction JavaDoc {
172         public void actionPerformed(ActionEvent JavaDoc e) {
173             dispose();
174         }
175     }
176
177     /**
178      * The panel that contains the viewer.
179      */

180     public class Panel extends JPanel JavaDoc {
181     /**
182      * The DOM document.
183      */

184     protected Document JavaDoc document;
185
186     /**
187      * The ViewCSS object associated with the document.
188      */

189     protected ViewCSS viewCSS;
190
191     /**
192      * The tree.
193      */

194     protected JTree JavaDoc tree;
195
196     /**
197      * The split pane.
198      */

199     protected JSplitPane JavaDoc splitPane;
200
201     /**
202      * The right panel.
203      */

204     protected JPanel JavaDoc rightPanel = new JPanel JavaDoc(new BorderLayout JavaDoc());
205
206     /**
207      * The attributes table.
208      */

209     protected JTable JavaDoc attributesTable = new JTable JavaDoc();
210
211     /**
212      * The properties table.
213      */

214     protected JTable JavaDoc propertiesTable = new JTable JavaDoc();
215
216     /**
217      * The element panel.
218      */

219     protected JPanel JavaDoc elementPanel = new JPanel JavaDoc(new GridLayout JavaDoc(2, 1));
220     {
221         JScrollPane JavaDoc pane = new JScrollPane JavaDoc();
222         pane.setBorder(BorderFactory.createCompoundBorder
223                (BorderFactory.createEmptyBorder(2, 0, 2, 2),
224                 BorderFactory.createCompoundBorder
225                 (BorderFactory.createTitledBorder
226                  (BorderFactory.createEmptyBorder(),
227                   resources.getString("AttributesPanel.title")),
228                  BorderFactory.createLoweredBevelBorder())));
229         pane.getViewport().add(attributesTable);
230             
231         JScrollPane JavaDoc pane2 = new JScrollPane JavaDoc();
232         pane2.setBorder(BorderFactory.createCompoundBorder
233                 (BorderFactory.createEmptyBorder(2, 0, 2, 2),
234                  BorderFactory.createCompoundBorder
235                  (BorderFactory.createTitledBorder
236                   (BorderFactory.createEmptyBorder(),
237                    resources.getString("CSSValuesPanel.title")),
238                   BorderFactory.createLoweredBevelBorder())));
239         pane2.getViewport().add(propertiesTable);
240             
241         elementPanel.add(pane);
242         elementPanel.add(pane2);
243     }
244
245     /**
246      * The CharacterData panel text area.
247      */

248     protected JTextArea JavaDoc characterData = new JTextArea JavaDoc();
249
250     /**
251      * The CharacterData node panel.
252      */

253     protected JPanel JavaDoc characterDataPanel = new JPanel JavaDoc(new BorderLayout JavaDoc());
254     {
255         characterDataPanel.setBorder
256                 (BorderFactory.createCompoundBorder
257                  (BorderFactory.createEmptyBorder(2, 0, 2, 2),
258                   BorderFactory.createCompoundBorder
259                   (BorderFactory.createTitledBorder
260                    (BorderFactory.createEmptyBorder(),
261                     resources.getString("CDataPanel.title")),
262                    BorderFactory.createLoweredBevelBorder())));
263         JScrollPane JavaDoc pane = new JScrollPane JavaDoc();
264         pane.getViewport().add(characterData);
265         characterDataPanel.add(pane);
266         characterData.setEditable(false);
267     }
268
269     /**
270      * The documentInfo panel text area.
271      */

272     protected JTextArea JavaDoc documentInfo = new JTextArea JavaDoc();
273
274     /**
275      * The documentInfo node panel.
276      */

277     protected JPanel JavaDoc documentInfoPanel = new JPanel JavaDoc(new BorderLayout JavaDoc());
278     {
279         documentInfoPanel.setBorder
280                 (BorderFactory.createCompoundBorder
281                  (BorderFactory.createEmptyBorder(2, 0, 2, 2),
282                   BorderFactory.createCompoundBorder
283                   (BorderFactory.createTitledBorder
284                    (BorderFactory.createEmptyBorder(),
285                     resources.getString("DocumentInfoPanel.title")),
286                    BorderFactory.createLoweredBevelBorder())));
287         JScrollPane JavaDoc pane = new JScrollPane JavaDoc();
288         pane.getViewport().add(documentInfo);
289         documentInfoPanel.add(pane);
290         documentInfo.setEditable(false);
291     }
292
293     /**
294      * Creates a new Panel object.
295      */

296     public Panel() {
297         super(new BorderLayout JavaDoc());
298         setBorder(BorderFactory.createTitledBorder
299               (BorderFactory.createEmptyBorder(),
300                resources.getString("DOMViewerPanel.title")));
301
302         TreeNode JavaDoc root;
303         root = new DefaultMutableTreeNode JavaDoc
304                 (resources.getString("EmptyDocument.text"));
305         tree = new JTree JavaDoc(root);
306         tree.setCellRenderer(new NodeRenderer());
307         tree.putClientProperty("JTree.lineStyle", "Angled");
308
309         JScrollPane JavaDoc treePane = new JScrollPane JavaDoc();
310         treePane.setBorder(BorderFactory.createCompoundBorder
311                    (BorderFactory.createEmptyBorder(2, 2, 2, 0),
312                 BorderFactory.createCompoundBorder
313                 (BorderFactory.createTitledBorder
314                  (BorderFactory.createEmptyBorder(),
315                   resources.getString("DOMViewer.title")),
316                  BorderFactory.createLoweredBevelBorder())));
317         treePane.getViewport().add(tree);
318         splitPane = new JSplitPane JavaDoc(JSplitPane.HORIZONTAL_SPLIT,
319                        true, // Continuous layout
320
treePane,
321                        rightPanel);
322         int loc = resources.getInteger("SplitPane.dividerLocation");
323         splitPane.setDividerLocation(loc);
324         add(splitPane);
325         
326         tree.addTreeSelectionListener(new DOMTreeSelectionListener());
327     }
328
329     /**
330      * Sets the document to display.
331      */

332     public void setDocument(Document JavaDoc doc) {
333         setDocument(doc, null);
334     }
335
336     /**
337      * Sets the document to display and its ViewCSS.
338      */

339     public void setDocument(Document JavaDoc doc, ViewCSS view) {
340         document = doc;
341         viewCSS = view;
342         TreeNode JavaDoc root = createTree(doc, showWhitespace);
343         ((DefaultTreeModel JavaDoc)tree.getModel()).setRoot(root);
344         if (rightPanel.getComponentCount() != 0) {
345         rightPanel.remove(0);
346         splitPane.revalidate();
347         splitPane.repaint();
348         }
349     }
350
351     /**
352      * Creates a swing tree from a DOM document.
353      */

354     protected MutableTreeNode JavaDoc createTree(Node JavaDoc node,
355                                              boolean showWhitespace) {
356         DefaultMutableTreeNode JavaDoc result;
357         result = new DefaultMutableTreeNode JavaDoc(new NodeInfo(node));
358         for (Node JavaDoc n = node.getFirstChild();
359                  n != null;
360                  n = n.getNextSibling()) {
361                 if (!showWhitespace && (n instanceof org.w3c.dom.Text JavaDoc)) {
362                     String JavaDoc txt = n.getNodeValue();
363                     if (txt.trim().length() == 0)
364                         continue;
365                 }
366                     result.add(createTree(n, showWhitespace));
367         }
368         return result;
369     }
370
371     /**
372      * To listen to the tree selection.
373      */

374     protected class DOMTreeSelectionListener
375             implements TreeSelectionListener JavaDoc {
376         /**
377          * Called when the selection changes.
378          */

379         public void valueChanged(TreeSelectionEvent JavaDoc ev) {
380         DefaultMutableTreeNode JavaDoc mtn;
381         mtn =
382                     (DefaultMutableTreeNode JavaDoc)tree.getLastSelectedPathComponent();
383         if (mtn == null) {
384             return;
385         }
386
387         if (rightPanel.getComponentCount() != 0) {
388             rightPanel.remove(0);
389         }
390
391         Object JavaDoc nodeInfo = mtn.getUserObject();
392         if (nodeInfo instanceof NodeInfo) {
393             Node JavaDoc node = ((NodeInfo)nodeInfo).getNode();
394             switch (node.getNodeType()) {
395             case Node.DOCUMENT_NODE:
396             documentInfo.setText
397                             (createDocumentText((Document JavaDoc)node));
398             rightPanel.add(documentInfoPanel);
399                         break;
400             case Node.ELEMENT_NODE:
401             attributesTable.setModel(new NodeAttributesModel(node));
402             propertiesTable.setModel(new NodeCSSValuesModel(node));
403             rightPanel.add(elementPanel);
404             break;
405             case Node.COMMENT_NODE:
406             case Node.TEXT_NODE:
407             case Node.CDATA_SECTION_NODE:
408             characterData.setText(node.getNodeValue());
409             rightPanel.add(characterDataPanel);
410             }
411         }
412         splitPane.revalidate();
413         splitPane.repaint();
414         }
415
416             protected String JavaDoc createDocumentText(Document JavaDoc doc) {
417                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
418                 sb.append("Nodes: ");
419                 sb.append(nodeCount(doc));
420                 return sb.toString();
421             }
422
423             protected int nodeCount(Node JavaDoc node) {
424                 int result = 1;
425                 for (Node JavaDoc n = node.getFirstChild();
426                      n != null;
427                      n = n.getNextSibling()) {
428                     result += nodeCount(n);
429                 }
430                 return result;
431             }
432     }
433
434     /**
435      * To render the tree nodes.
436      */

437     protected class NodeRenderer extends DefaultTreeCellRenderer JavaDoc {
438         /**
439          * The icon used to represent elements.
440          */

441         ImageIcon JavaDoc elementIcon;
442
443         /**
444          * The icon used to represent comments.
445          */

446         ImageIcon JavaDoc commentIcon;
447
448         /**
449          * The icon used to represent processing instructions.
450          */

451         ImageIcon JavaDoc piIcon;
452
453         /**
454          * The icon used to represent text.
455          */

456         ImageIcon JavaDoc textIcon;
457
458         /**
459          * Creates a new NodeRenderer object.
460          */

461         public NodeRenderer() {
462         String JavaDoc s;
463         s = resources.getString("Element.icon");
464         elementIcon = new ImageIcon JavaDoc(getClass().getResource(s));
465         s = resources.getString("Comment.icon");
466         commentIcon = new ImageIcon JavaDoc(getClass().getResource(s));
467         s = resources.getString("PI.icon");
468         piIcon = new ImageIcon JavaDoc(getClass().getResource(s));
469         s = resources.getString("Text.icon");
470         textIcon = new ImageIcon JavaDoc(getClass().getResource(s));
471         }
472
473         /**
474          * Sets the value of the current tree cell.
475          */

476         public Component JavaDoc getTreeCellRendererComponent(JTree JavaDoc tree,
477                               Object JavaDoc value,
478                               boolean sel,
479                               boolean expanded,
480                               boolean leaf,
481                               int row,
482                               boolean hasFocus) {
483         super.getTreeCellRendererComponent(tree, value, sel, expanded,
484                            leaf, row, hasFocus);
485         switch (getNodeType(value)) {
486         case Node.ELEMENT_NODE:
487             setIcon(elementIcon);
488             break;
489         case Node.COMMENT_NODE:
490             setIcon(commentIcon);
491             break;
492         case Node.PROCESSING_INSTRUCTION_NODE:
493             setIcon(piIcon);
494             break;
495         case Node.TEXT_NODE:
496         case Node.CDATA_SECTION_NODE:
497             setIcon(textIcon);
498             break;
499         }
500         return this;
501         }
502
503         /**
504          * Returns the DOM type of the given object.
505          * @return the type or -1.
506          */

507         protected short getNodeType(Object JavaDoc value) {
508         DefaultMutableTreeNode JavaDoc mtn = (DefaultMutableTreeNode JavaDoc)value;
509         Object JavaDoc obj = mtn.getUserObject();
510         if (obj instanceof NodeInfo) {
511             Node JavaDoc node = ((NodeInfo)obj).getNode();
512             return node.getNodeType();
513         }
514         return -1;
515         }
516     }
517
518     /**
519      * To display the attributes of a DOM node attributes in a table.
520      */

521     protected class NodeAttributesModel extends AbstractTableModel JavaDoc {
522         /**
523          * The node.
524          */

525             protected Node JavaDoc node;
526         
527         /**
528          * Creates a new NodeAttributesModel object.
529          */

530         public NodeAttributesModel(Node JavaDoc n) {
531         node = n;
532         }
533
534         /**
535          * Returns the name to give to a column.
536          */

537         public String JavaDoc getColumnName(int col) {
538         if (col == 0) {
539             return resources.getString("AttributesTable.column1");
540         } else {
541             return resources.getString("AttributesTable.column2");
542         }
543         }
544
545         /**
546          * Returns the number of columns in the table.
547          */

548         public int getColumnCount() {
549         return 2;
550         }
551
552         /**
553          * Returns the number of rows in the table.
554          */

555         public int getRowCount() {
556         return node.getAttributes().getLength();
557         }
558
559         /**
560          * Whether the given cell is editable.
561          */

562         public boolean isCellEditable(int row, int col) {
563         return false;
564         }
565
566         /**
567          * Returns the value of the given cell.
568          */

569         public Object JavaDoc getValueAt(int row, int col) {
570         NamedNodeMap JavaDoc map = node.getAttributes();
571         Node JavaDoc n = map.item(row);
572         if (col == 0) {
573             return n.getNodeName();
574         } else {
575             return n.getNodeValue();
576         }
577         }
578     }
579     
580     /**
581      * To display the CSS properties of a DOM node in a table.
582      */

583     protected class NodeCSSValuesModel extends AbstractTableModel JavaDoc {
584         /**
585          * The node.
586          */

587         protected Node JavaDoc node;
588
589             /**
590              * The computed style.
591              */

592             protected CSSStyleDeclaration style;
593         
594             /**
595              * The property names.
596              */

597             protected java.util.List JavaDoc propertyNames;
598
599         /**
600          * Creates a new NodeAttributesModel object.
601          */

602         public NodeCSSValuesModel(Node JavaDoc n) {
603         node = n;
604                 if (viewCSS != null) {
605                     style = viewCSS.getComputedStyle((Element JavaDoc)n, null);
606                     propertyNames = new ArrayList JavaDoc();
607                     if (style != null) {
608                         for (int i = 0; i < style.getLength(); i++) {
609                             propertyNames.add(style.item(i));
610                         }
611                         Collections.sort(propertyNames);
612                     }
613                 }
614         }
615
616         /**
617          * Returns the name to give to a column.
618          */

619         public String JavaDoc getColumnName(int col) {
620         if (col == 0) {
621             return resources.getString("CSSValuesTable.column1");
622         } else {
623             return resources.getString("CSSValuesTable.column2");
624         }
625         }
626
627         /**
628          * Returns the number of columns in the table.
629          */

630         public int getColumnCount() {
631         return 2;
632         }
633
634         /**
635          * Returns the number of rows in the table.
636          */

637         public int getRowCount() {
638         if (style == null) {
639             return 0;
640         }
641         return style.getLength();
642         }
643
644         /**
645          * Whether the given cell is editable.
646          */

647         public boolean isCellEditable(int row, int col) {
648         return false;
649         }
650
651         /**
652          * Returns the value of the given cell.
653          */

654         public Object JavaDoc getValueAt(int row, int col) {
655         String JavaDoc prop = (String JavaDoc)propertyNames.get(row);
656         if (col == 0) {
657             return prop;
658         } else {
659             return style.getPropertyValue(prop);
660         }
661         }
662     }
663     
664     } // class Panel
665

666     /**
667      * To store the nodes informations
668      */

669     protected static class NodeInfo {
670         /**
671          * The DOM node.
672          */

673         protected Node JavaDoc node;
674
675         /**
676          * Creates a new NodeInfo object.
677          */

678         public NodeInfo(Node JavaDoc n) {
679             node = n;
680         }
681
682         /**
683          * Returns the DOM Node associated with this node info.
684          */

685         public Node JavaDoc getNode() {
686             return node;
687         }
688
689         /**
690          * Returns a printable representation of the object.
691          */

692         public String JavaDoc toString() {
693             if (node instanceof Element JavaDoc) {
694                 String JavaDoc id = ((Element JavaDoc)node).getAttribute("id");
695                 if (id.length() != 0) {
696                     return node.getNodeName() + " \""+id+"\"";
697                 }
698             }
699             return node.getNodeName();
700         }
701     }
702 }
703
Popular Tags