📄 jaxpdom4.html
字号:
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>Displaying a DOM Hierarchy</title> <link rel="StyleSheet" href="document.css" type="text/css" media="all" /> <link rel="StyleSheet" href="catalog.css" type="text/css" media="all" /> <link rel="Table of Contents" href="J2EETutorialTOC.html" /> <link rel="Previous" href="JAXPDOM3.html" /> <link rel="Next" href="JAXPDOM5.html" /> <link rel="Index" href="J2EETutorialIX.html" /> </head> <body> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="JAXPDOM3.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="JAXPDOM5.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <blockquote><a name="wp64186"> </a><h2 class="pHeading1">Displaying a DOM Hierarchy</h2><a name="wp64187"> </a><p class="pBody">To create a Document Object Hierarchy (DOM) or manipulate one, it helps to have a clear idea of how the nodes in a DOM are structured. In this section of the tutorial, you'll expose the internal structure of a DOM. </p><a name="wp64189"> </a><h3 class="pHeading2">Echoing Tree Nodes</h3><a name="wp64190"> </a><p class="pBody">What you need at this point is a way to expose the nodes in a DOM so you can see what it contains. To do that, you'll convert a DOM into a <code class="cCode">JTreeModel</code> and display the full DOM in a <code class="cCode">JTree</code>. It's going to take a bit of work, but the end result will be a diagnostic tool you can use in the future, as well as something you can use to learn about DOM structure now.</p><a name="wp64192"> </a><h3 class="pHeading2">Convert DomEcho to a GUI App</h3><a name="wp64193"> </a><p class="pBody">Since the DOM is a tree, and the Swing <code class="cCode">JTree</code> component is all about displaying trees, it makes sense to stuff the DOM into a <code class="cCode">JTree</code>, so you can look at it. The first step in that process is to hack up the <code class="cCode">DomEcho</code> program so it becomes a GUI application. </p><hr><a name="wp64194"> </a><p class="pNote">Note: The code discussed in this section is in <code class="cCode"><a href="../examples/jaxp/dom/samples/DomEcho02.java" target="_blank">DomEcho02.java</a></code>.</p><hr><a name="wp64196"> </a><h4 class="pHeading3">Add Import Statements</h4><a name="wp64197"> </a><p class="pBody">Start by importing the GUI components you're going to need to set up the application and display a <code class="cCode">JTree</code>:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">// GUI components and layouts<code class="cCodeBold">import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTree; </code><a name="wp64198"> </a></pre></div><a name="wp64199"> </a><p class="pBody">Later on in the DOM tutorial, we'll tailor the DOM display to generate a user-friendly version of the <code class="cCode">JTree</code> display. When the user selects an element in that tree, you'll be displaying subelements in an adjacent editor pane. So, while we're doing the setup work here, import the components you need to set up a divided view (<code class="cCode">JSplitPane</code>) and to display the text of the subelements (<code class="cCode">JEditorPane</code>):</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><code class="cCodeBold">import javax.swing.JSplitPane;import javax.swing.JEditorPane;</code> <a name="wp64200"> </a></pre></div><a name="wp64201"> </a><p class="pBody">Add a few support classes you're going to need to get this thing off the ground:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">// GUI support classes<code class="cCodeBold">import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.Toolkit;import java.awt.event.WindowEvent;import java.awt.event.WindowAdapter;</code> <a name="wp64202"> </a></pre></div><a name="wp64203"> </a><p class="pBody">Finally, import some classes to make a fancy border:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">// For creating borders<code class="cCodeBold">import javax.swing.border.EmptyBorder;import javax.swing.border.BevelBorder;import javax.swing.border.CompoundBorder;</code> <a name="wp64204"> </a></pre></div><a name="wp64205"> </a><p class="pBody">(These are optional. You can skip them and the code that depends on them if you want to simplify things.) </p><a name="wp64207"> </a><h4 class="pHeading3">Create the GUI Framework</h4><a name="wp64208"> </a><p class="pBody">The next step is to convert the application into a GUI application. To do that, the static main method will create an instance of the main class, which will have become a GUI pane.</p><a name="wp64209"> </a><p class="pBody">Start by converting the class into a GUI pane by extending the Swing <code class="cCode">JPanel</code> class: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class DomEcho02 <code class="cCodeBold">extends JPanel</code>{ // Global value so it can be ref'd by the tree-adapter static Document document; ...<a name="wp64210"> </a></pre></div><a name="wp64211"> </a><p class="pBody">While you're there, define a few constants you'll use to control window sizes: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class DomEcho02 extends JPanel{ // Global value so it can be ref'd by the tree-adapter static Document document; <a name="wp64212"> </a> <code class="cCodeBold">static final int windowHeight = 460; static final int leftWidth = 300; static final int rightWidth = 340; static final int windowWidth = leftWidth + rightWidth;</code> <a name="wp64213"> </a></pre></div><a name="wp64214"> </a><p class="pBody">Now, in the main method, invoke a method that will create the outer frame that the GUI pane will sit in:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public static void main(String argv[]){ ... DocumentBuilderFactory factory ... try { DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse( new File(argv[0]) ); <code class="cCodeBold">makeFrame();</code><a name="wp64215"> </a> } catch (SAXParseException spe) { ...<a name="wp64216"> </a></pre></div><a name="wp64217"> </a><p class="pBody">Next, you'll need to define the <code class="cCode">makeFrame</code> method itself. It contains the standard code to create a frame, handle the exit condition gracefully, give it an instance of the main panel, size it, locate it on the screen, and make it visible: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"> ...} // main<a name="wp64218"> </a><code class="cCodeBold">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 DomEcho02 echoPanel = new DomEcho02(); 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</code><a name="wp66568"> </a></pre></div><a name="wp64222"> </a><h4 class="pHeading3">Add the Display Components</h4><a name="wp64223"> </a><p class="pBody">The only thing left in the effort to convert the program to a GUI application is to create the class constructor and make it create the panel's contents. Here is the constructor:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class DomEcho02 extends JPanel{ ... static final int windowWidth = leftWidth + rightWidth; <code class="cCodeBold">public DomEcho02() { } // Constructor</code><a name="wp64224"> </a></pre></div><a name="wp64225"> </a><p class="pBody">Here, you make use of the border classes you imported earlier to make a regal border (optional):</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02(){ // Make a nice border <code class="cCodeBold">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));</code>} // Constructor<a name="wp64226"> </a></pre></div><a name="wp64228"> </a><p class="pBody">Next, create an empty tree and put it a <code class="cCode">JScrollPane</code> so users can see its contents as it gets large: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02({ ...<code class="cCodeBold"> // Set up the tree JTree tree = new JTree();</code> // Build left-side view<code class="cCodeBold"> JScrollPane treeView = new JScrollPane(tree); treeView.setPreferredSize( new Dimension( leftWidth, windowHeight ));</code>} // Constructor<a name="wp64229"> </a></pre></div><a name="wp64233"> </a><p class="pBody">Now create a non-editable <code class="cCode">JEditPane</code> that will eventually hold the contents pointed to by selected <code class="cCode">JTree</code> nodes:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02({ .... // Build right-side view<code class="cCodeBold"> JEditorPane htmlPane = new JEditorPane("text/html",""); htmlPane.setEditable(false); JScrollPane htmlView = new JScrollPane(htmlPane); htmlView.setPreferredSize( new Dimension( rightWidth, windowHeight ));</code>} // Constructor<a name="wp64234"> </a></pre></div><a name="wp64237"> </a><p class="pBody">With the left-side <code class="cCode">JTree</code> and the right-side <code class="cCode">JEditorPane</code> constructed, create a <code class="cCode">JSplitPane</code> to hold them: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02(){ .... // Build split-pane view <code class="cCodeBold">JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeView, htmlView ); splitPane.setContinuousLayout( true ); splitPane.setDividerLocation( leftWidth ); splitPane.setPreferredSize( new Dimension( windowWidth + 10, windowHeight+10 ));</code>} // Constructor<a name="wp64238"> </a></pre></div><a name="wp64241"> </a><p class="pBody">With this code, you set up the <code class="cCode">JSplitPane</code> with a vertical divider. That produces a "horizontal split" between the tree and the editor pane. (More of a horizontal layout, really.) You also set the location of the divider so that the tree got the width it prefers, with the remainder of the window width allocated to the editor pane.</p><a name="wp64242"> </a><p class="pBody"> Finally, specify the layout for the panel and add the split pane: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02(){ ... // Add GUI components <code class="cCodeBold">this.setLayout(new BorderLayout()); this.add("Center", splitPane );</code>} // Constructor <a name="wp64243"> </a></pre></div><a name="wp64244"> </a><p class="pBody">Congratulations! The program is now a GUI application. You can run it now to see what the general layout will look like on screen. For reference, here is the completed constructor:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public DomEcho02(){ // 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)); // Set up the tree JTree tree = new JTree(); // Build left-side view JScrollPane 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 GUI components this.setLayout(new BorderLayout()); this.add("Center", splitPane );} // Constructor <a name="wp64245"> </a></pre></div><a name="wp64247"> </a><h3 class="pHeading2">Create Adapters to Display the DOM in a JTree</h3><a name="wp64248"> </a><p class="pBody">Now that you have a GUI framework to display a <code class="cCode">JTree</code> in, the next step is get the <code class="cCode">JTree</code> to display the DOM. But a <code class="cCode">JTree</code> wants to display a <code class="cCode">TreeModel</code>. A DOM is a tree, but it's not a <code class="cCode">TreeModel</code>. So you'll need to create an adapter class that makes the DOM look like a <code class="cCode">TreeModel</code> to a <code class="cCode">JTree</code>. </p><a name="wp64249"> </a><p class="pBody">Now, when the <code class="cCode">TreeModel</code> passes nodes to the <code class="cCode">JTree</code>, <code class="cCode">JTree</code> uses the <code class="cCode">toString</code> function of those nodes to get the text to display in the tree. The standard <code class="cCode">toString</code> function isn't going to be very pretty, so you'll need to wrap the DOM nodes in an <code class="cCode">AdapterNode</code> that returns the text we want. What the <code class="cCode">TreeModel</code> gives to the <code class="cCode">JTree</code>, then, will in fact be <code class="cCode">AdapterNode</code> objects that wrap DOM nodes.</p><hr><a name="wp64250"> </a><p class="pNote">Note: The classes that follow are defined as inner classes. If you are coding for the 1.1 platform, you will need to define these class as external classes. </p><hr><a name="wp64252"> </a><h4 class="pHeading3">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -