⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3_display.html

📁 XML_JAVA指南 书籍语言: 简体中文 书籍类型: 程序设计 授权方式: 免费软件 书籍大小: 377 KB
💻 HTML
📖 第 1 页 / 共 3 页
字号:
    regardless of the system the data comes from. That makes programming quite     a bit simpler. </p></blockquote><p>Wrapping a DomNode and returning the desired string are the AdapterNode's major   functions. But since the TreeModel adapter will need to answer questions like   &quot;How many children does this node have?&quot; and satisfy commands like   &quot;Give me this node's Nth child&quot;, it will helpful to define a few additional   utility methods. (The adapter could always access the DOM node and get that   information for itself, but this way things are more encapsulated.)</p><p>Add the code highlighted below to <new></new><new>return the index of a specified   child, the child that corresponds to a given index, and the count of child nodes:</new><new></new></p> <blockquote>   <p></p>  <pre>    <new>public class AdapterNode </new>    <new>{ </new>      ...      <new>public String toString() {</new>        <new>...</new>      <new>}</new>      <new></new><new><b>public int index(AdapterNode child) {</b></new>        <new><b>//System.err.println("Looking for index of " + child);</b></new>        <new><b>int count = childCount();</b></new>        <new><b>for (int i=0; i&lt;count; i++) {</b></new>          <new><b>AdapterNode n = this.child(i);</b></new>          <new><b>if (child == n) return i;</b></new>        <new><b>}</b></new>        <new><b>return -1; // Should never get here.</b></new>      <new><b>}</b></new>      <new><b>public AdapterNode child(int searchIndex) {</b></new>        <new><b>//Note: JTree index is zero-based. </b></new>        <new><b>org.w3c.dom.Node node = domNode.getChildNodes().item(searchIndex);</b></new>        <new><b>return new AdapterNode(node); </b></new>      <new><b>}</b></new>      <new><b>public int childCount() {</b></new>          <new><b>return domNode.getChildNodes().getLength();  </b></new>      <new><b>}</b></new>    <new>}</new> // AdapterNode} // DomEcho</pre>  <p>   <p><b>Note:</b><br>    During development, it was only after I started writing the TreeModel adapter     that I realized these were needed, and went back to add them. In just a moment,     you'll see why. </p></blockquote><h4><a name="TreeModel"></a>Define the TreeModel Adapter</h4><p></p><p>Now, at last, you are ready to write the TreeModel adapter. One of the really   nice things about the JTree model is the relative ease with which you convert   an existing tree for display. One of the reasons for that is the clear separation   between the displayable view, which JTree uses, and the modifiable view, which   the application uses. For more on that separation, see <a href="http://java.sun.com/products/jfc/tsc/articles/jtree/index.html">Understanding   the TreeModel</a>. For now, the important point is that to satisfy the TreeModel   interface we only need to (a) provide methods to access and report on children   and (b) register the appropriate JTree listener, so it knows to update its view   when the underlying model changes.</p><p>Add the code highlighted below to create the TreeModel adapter and specify   the child-processing methods:</p><blockquote>   <p></p>  <pre>      ...    <new>}</new> // AdapterNode</pre>  <p>   <pre>    <new><b>// This adapter converts the current Document (a DOM) into </b></new>    <new><b>// a JTree model. </b></new>    <new><b>public class DomToTreeModelAdapter implements javax.swing.tree.TreeModel </b></new>    <new><b>{</b></new>      <new><b>// Basic TreeModel operations</b></new>      <new><b>public Object  getRoot() {</b></new>        <new><b>//System.err.println("Returning root: " +document);</b></new>        <new><b>return new AdapterNode(document);</b></new>      <new><b>}</b></new>      <new><b>public boolean isLeaf(Object aNode) {</b></new>        <new><b>// Determines whether the icon shows up to the left.</b></new>        <new><b>// Return true for any node with no children</b></new>        <new><b>AdapterNode node = (AdapterNode) aNode;</b></new>        <new><b>if (node.childCount() &gt; 0) return false;</b></new>        <new><b>return true;</b></new>      <new><b>}</b></new>      <new><b>public int     getChildCount(Object parent) {</b></new>        <new><b>AdapterNode node = (AdapterNode) parent;</b></new>        <new><b>return node.childCount();</b></new>      <new><b>}</b></new>      <new><b>public Object  getChild(Object parent, int index) {</b></new>        <new><b>AdapterNode node = (AdapterNode) parent;</b></new>        <new><b>return node.child(index);</b></new>      <new><b>}</b></new>      <new><b>public int     getIndexOfChild(Object parent, Object child) {</b></new>        <new><b>AdapterNode node = (AdapterNode) parent;</b></new>        <new><b>return node.index((AdapterNode) child);</b></new>      <new><b>}</b></new>      <new><b>public void    valueForPathChanged(TreePath path, Object newValue) {</b></new>        <new><b>// Null. We won't be making changes in the GUI</b></new>        <new><b>// If we did, we would ensure the new value was really new</b></new>        <new><b>// and then fire a TreeNodesChanged event.</b></new>      <new><b>}</b></new>    <new><b>}</b></new><b> // DomToTreeModelAdapter</b>} // DomEcho  </pre></blockquote><blockquote> </blockquote><p>In this code, the <tt>getRoot</tt> method returns the root node of the DOM,   wrapped as an AdapterNode object. From here on, all nodes returned by the adapter   will be AdapterNodes that wrap DOM nodes. By the same token, whenever the JTree   asks for the child of a given parent, the number of children that parent has,   etc., the JTree will be passing us an AdapterNode. We know that, because we   control every node the JTree sees, starting with the root node.<p> JTree uses the isLeaf method to determine whether or not to display a clickable   expand/contract icon to the left of the node, so that method returns true only   if the node has children. In this method, we see the cast from the generic object   JTree sends us to the AdapterNode object we know it has to be. *We* know it   is sending us an adapter object, but the interface, to be general, defines objects,   so we have to do the casts.<p>The next three methods return the number of children for a given node, the   child that lives at a given index, and the index of a given child, respectively.   That's all pretty straightforward. </p><p>The last method is invoked when the user changes a value stored in the JTree.   In this app, we won't support that. But if we did, the app would have to make   the change to the underlying model and then inform any listeners that a change   had occurred. (The JTree might not be the only listener. In many an application   it isn't, in fact.) </p><blockquote>   <p> </blockquote><p>To inform listeners that a change occurred, you'll need the ability to register   them. That brings us to the last two methods required to implement the TreeModel   interface. Add the code highlighted below to define them: </p><blockquote>   <pre><new>public class DomToTreeModelAdapter ...</new><new>{</new>  <new>...</new>  <new>public void    valueForPathChanged(TreePath path, Object newValue) {</new>    <new>...</new>  <new>}</new>      <new></new>  <new><b>private Vector listenerList = new Vector();</b></new>  <new><b>public void addTreeModelListener( TreeModelListener listener ) {</b></new>    <new><b>if ( listener != null &amp;&amp; ! listenerList.contains( listener ) ) {</b></new>       <new><b>listenerList.addElement( listener );</b></new>    <new><b>}</b></new>  <new><b>}</b></new>  <new><b>public void removeTreeModelListener( TreeModelListener listener ) {</b></new>    <new><b>if ( listener != null ) {</b></new>       <new><b>listenerList.removeElement( listener );</b></new>    <new><b>}</b></new>  <new><b>}</b></new><new>}</new> // DomToTreeModelAdapter</pre>  <p> </blockquote><new>Since this app won't be making changes</new> to the tree, these methods will go unused, for now. However, they'll be there in the future, when you need them.<new></new> <blockquote>   <p><new><b>Note:</b><br>    This example uses Vector so it will work with 1.1 apps.</new> <new> If coding     for 1.2 or later, though, I'd use the excellent collections framework instead:</new></p>  <blockquote>     <p><new> private LinkedList listenerList = new LinkedList();</new></p>  </blockquote>  <p> <new>The operations on the List are then <tt>add</tt> and <tt>remove</tt>.     To iterate over the list, as in the operations below, you would use:</new></p>  <blockquote>     <pre>Iterator it = listenerList.iterator();w<new>hile ( it.hasNext() ) {</new>  <new>TreeModelListener listener = (TreeModelListener)it.next();  </new><new> ...</new> <new>}</new></pre>  </blockquote></blockquote><p>Here, too, are some optional methods you won't be using in this app. At this   point, though, you have constructed a reasonable template for a TreeModel adapter.   In the interests of completeness, you might want to add the code highlighted   below. You can then invoke them whenever you need to notify JTree listeners   of a change:<blockquote>   <pre>  <new>public void removeTreeModelListener( TreeModelListener listener ) {</new>    <new>...</new><new></new>  <new>}</new>   <new><b>public void fireTreeNodesChanged( TreeModelEvent e ) {</b></new>    <new><b>Enumeration listeners = listenerList.elements();</b></new>    <new><b>while ( listeners.hasMoreElements() ) {</b></new>      <new><b>TreeModelListener listener = (TreeModelListener)listeners.nextElement();</b></new>      <new><b>listener.treeNodesChanged( e );</b></new>    <new><b>}</b></new>  <new><b>} </b></new>  <new><b>public void fireTreeNodesInserted( TreeModelEvent e ) {</b></new>    <new><b>Enumeration listeners = listenerList.elements();</b></new>    <new><b>while ( listeners.hasMoreElements() ) {</b></new>       <new><b>TreeModelListener listener = (TreeModelListener)listeners.nextElement();</b></new>       <new><b>listener.treeNodesInserted( e );</b></new>    <new><b>}</b></new>  <new><b>}   </b></new>  <new><b>public void fireTreeNodesRemoved( TreeModelEvent e ) {</b></new>    <new><b>Enumeration listeners = listenerList.elements();</b></new>    <new><b>while ( listeners.hasMoreElements() ) {</b></new>      <new><b>TreeModelListener listener = (TreeModelListener)listeners.nextElement();</b></new>      <new><b>listener.treeNodesRemoved( e );</b></new>    <new><b>}</b></new>  <new><b>}   </b></new>  <new><b>public void fireTreeStructureChanged( TreeModelEvent e ) {</b></new>    <new><b>Enumeration listeners = listenerList.elements();</b></new>    <new><b>while ( listeners.hasMoreElements() ) {</b></new>      <new><b>TreeModelListener listener = (TreeModelListener)listeners.nextElement();</b></new>      <new><b>listener.treeStructureChanged( e );</b></new>    <new><b>}</b></new>  <new><b>}</b></new><new>}</new> // DomToTreeModelAdapter</pre>  <p><new><b>Note:</b></new><br>    <new>These methods are taken from the TreeModelSupport class described in     </new><new></new><new><a href="http://java.sun.com/products/jfc/tsc/articles/jtree/index.html">Understanding     the TreeModel</a>. That architecture was produced by Tom Santos and Steve     Wilson, and is a lot more elegant than the quick hack going on here. It seemed     worthwhile to put them here, though, so they would be immediately at hand     when and if they're needed.</new><new>.</new> </p>  </blockquote><h3><a name="finish"></a>Finish it Up </h3><p>At this point, you are basically done. All you need to do is jump back to the   constructor and add the code to construct an adapter and deliver it to the JTree   as the TreeModel:</p><blockquote>   <pre><new><b>// Set up the tree</b></new><new>JTree tree = new JTree(<b>new DomToTreeModelAdapter()</b>);</new> </pre></blockquote><p>You can now compile and run the code on an XML file. In the next section, will   explore what you see when you do that. </p><blockquote>   <p>   <hr size=4></blockquote><p> <p> <table width="100%">  <tr>     <td align=left> <ahref="2_anydata.html"><img src="../images/PreviousArrow.gif" width=26 height=26 align=bottom border=0 alt="Previous | "></a><ahref="3b_display.html"><img src="../images/NextArrow.gif" width=26 height=26 align=top border=0 alt="Next | "></a><a href="../alphaIndex.html"><img src="../images/xml_IDX.gif" width=26 height=26 align=top border=0 alt="Index | "></a><a href="../TOC.html"><imgsrc="../images/xml_TOC.gif" width=26 height=26 align=top border=0 alt="TOC | "></a><a href="../index.html"><imgsrc="../images/xml_Top.gif" width=26 height=26 align=top border=0 alt="Top | "></a>     </td>    <td align=right><strong><em><a href="index.html">Top</a></em></strong> <a href="../TOC.html#intro"><strong><em>Contents</em></strong></a>       <a href="../TOC.html#intro"><strong><em></em></strong></a> <a href="../alphaIndex.html"><strong><em>Index</em></strong></a>       <a href="../glossary.html"><strong><em>Glossary</em></strong></a></td>  </tr></table></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -