隨筆 - 3, 文章 - 152, 評論 - 17, 引用 - 0
          數據加載中……

          文檔對象模型

          Eric Armstrong

          SAX一章中已經編寫了包含用于放映的幻燈片的XML文件。然后又使用SAX APIXML回送到顯示器。

          本章中,將使用文檔對象模型(DOM)建立一個小的SlideShow應用程序。首先構建DOM并查看它,然后看看如何編寫XML結構的DOM ,將它顯示在GUI中,并且操作樹結構。

          文檔對象模型是普通的樹結構,每個節點包含一個來自于XML結構的組件。兩種最常見的節點類型是元素節點(element node)和文本節點(text node)。使用DOM函數能夠創建節點、刪除節點、改變節點內容并且遍歷節點層次。

          本章將解析現有的XML文件以構建DOM,顯示并查看DOM的層次結構,將DOM轉換成能夠友好顯示的Jtree,并且展現命名空間的語法。你將從頭開始創建一個DOM,并且了解如何使用SunJAXP實現的一些特定實現性能將現有的數據集轉換成XML

          首先要確信,在你的應用程序中DOM是最好的選擇。下一節何時使用DOM將具體介紹它。


          注意:可以在下面的頁面中找到本章的例子<JWSDP_HOME>/docs/tutorial/examples/jaxp/dom/samples.

          何時使用DOM

          文檔對象模型 (DOM) 是一個文檔標準(例如,文章和書)。另外,JAXP 1.2實現支持XML Schema,在任何給定的應用程序中必須慎重考慮這一點。

          另外,如果你正在處理簡單數據結構,并且XML Schema不是你計劃的一部分,那么你可能會發現一個面向對象的標準如JDOM dom4j 更加適合于實現你的目標。

          DOM從一開始就是一種與語言無關的模型。這是因為它專門用于像CPerl這類語言,沒有利用Java的面向對象的性能。這個事實再加上文檔/數據定義,也能幫助解釋處理DOM和處理JDOMdom4j結構之間的區別。

          本節中,將討論遵守這些標準的模型之間的區別,以便能夠幫助你為應用程序選擇最合適的模型。

            文檔vs.數據

          DOM中使用的文檔模型和JDOMdom4j中使用的數據模型的主要區別在于:

          ·   層次結構中的節點類型

          ·   “混合內容”的性能

          正是構成數據層次結構的 “節點” 的不同造成了這兩個模型之間編程的區別。然而,只有混合內容的性能能解釋不同標準定義“節點”有何區別。所以,首先來看看DOM的“混合內容模型”。

          混合內容模型

          回想在對文檔-驅動編程 (DDP) 的討論中,可以將文本和元素自由結合到DOM層次結構中。這種結構被稱為DOM模型中的“混合內容”。

          文檔中經常出現混合內容。例如,為了表示該結構:

          <sentence>This is an <bold>important</bold> idea.</sentence>

          DOM節點的層次結構看起來跟下面的很像,其中每行代表一個節點:

          ELEMENT: sentence

            +  TEXT: This is an

            +  ELEMENT: bold

              + TEXT: important

            + TEXT: idea.

          注意,句元素(sentence element)包含文本,后面跟著子元素,再后面是其他文本。 “混合內容模型”是通過將文本和元素混合起來而定義的。

          節點種類

          為了提供混合內容的性能,DOM節點生來就非常簡單。例如,在前面的例子中,第一個元素的內容 (它的value)簡單地標識了節點的類型。

          DOM用戶第一次通常都會被這個事實迷惑。到訪過<sentence> 節點后,他們就想要節點的“內容”,并且想得到其他有用信息。但是,它們得到的是元素的名字“sentence”。

          注意:DOM Node API定義了nodeValue()node.nodeType()nodeName() 方法。對于第一個元素節點,nodeName() 返回 "sentence",而nodeValue() 返回空。對于第一個文本節點, nodeName() 返回"#text",并且nodeValue() 返回"This is an "。很重要的一點是元素的value 和它的content不一樣。


          處理DOM時,獲得關心的內容意味著要檢查節點包含的子元素列表,忽略那些不感興趣的,只處理那些感興趣的。

          例如,在上面的例子中,如果要查詢句子的“text(文本)”意味著什么?根據你的應用程序,下面的每一條都是合理的:

          ·   This is an

          ·   This is an idea.

          ·   This is an important idea.

          ·   This is an <bold>important</bold> idea.

          簡單模型

          使用DOM可以方便地創建所需的語義。然而,也需要經過必要的處理,以實現這些語義。而像JDOMdom4j這樣的標準,使得事情更加簡單,因為層次結構中的每個節點都是一個對象。

          雖然JDOM dom4j 允許使用混合內容元素,但是它們主要不是用于這類情況的。相反,它們主要用于XML結構包含數據的應用程序中。

          傳統數據處理中所介紹的,數據結構中的元素包含文本或其他元素,但是不能兩個都包含。例如,下面的XML表示簡單的通訊簿:

          <addressbook>

            <entry>

              <name>Fred</name>

              <email>fred@home</email>

            </entry>

              ...

          </addressbook>


          注意: 對于這類非常簡單的XML數據結構,也可以使用Java平臺1.4版本中的正則表達式包(java.util.regex)


          JDOM dom4j中,一旦到達包含文本的元素,就會調用一個方法如text() 來獲得它的內容。處理DOM時,必須查看子元素列表,將節點的文本“放在一起”,就如前面所見到的——即便該列表只包含一項(TEXT 節點)

          所以,對于簡單的數據結構(如前面的通訊簿),使用JDOMdom4j可以節省很多工作。即便是數據在技術上是“混合”的,也可以使用這些模型中的某個模型,除非給定節點有一個(并且僅有一個)文本段。

          下面是這類結構的一個例子,它在JDOMdom4j中也很容易處理:

          <addressbook>

            <entry>Fred

              <email>fred@home</email>

            </entry>

             ...

          </addressbook>

          這里,每項都有標識文本,并且后面還有其他元素。使用該結構,程序能夠瀏覽一個項,調用text() 來查看它屬于誰,并且如果<email> 子元素在當前節點下,就處理它。

          增加復雜度

          但是要完全理解查找或操作DOM時需要進行的處理,就必需知道DOM包含的節點。

          下面的例子主要就是針對這點的。它是該數據的一個表示法:

          <sentence>

            The &projectName; <![CDATA[<i>project</i>]]> is

            <?editor: red><bold>important</bold><?editor: normal>.

          </sentence>

          該句子包含一個實體引用——一個在其他地方定義的指向“實體”的指針。這里,實體包含項目名。這個例子也包含CDATA(未解釋的數據,如HTML中的<pre> 數據),和處理指令 (<?...?>)。在本例中該處理指令告訴編輯器在繪制文本時使用哪種顏色。

          下面是該數據的DOM結構。它代表了強壯的應用程序要處理的結構:

          + ELEMENT: sentence

            + TEXT: The

            + ENTITY REF: projectName

              + COMMENT: The latest name we're using

              + TEXT: Eagle

            + CDATA: <i>project</i>

            + TEXT: is

            + PI: editor: red

            + ELEMENT: bold

              + TEXT: important

            + PI: editor: normal

          本例描繪了可能在DOM中出現的節點。雖然在絕大多數時候你的應用程序能夠忽略它們中的大部分,但是真正強壯的實現需要識別并處理它們中的每一個。

          同樣,到訪節點的處理涉及到子元素的處理,它忽略你不關心的元素僅僅查看關心的元素,直到找到感興趣的節點。

          通常,在這類情況下,僅對找到包含指定文本的節點感興趣。例如,在DOM API 中,有一個例子,那個例子中希望找到一個<coffee> 節點,該節點的<name> 元素包含文本“Mocha Java”。要執行該查找,程序需要處理<coffee> 元素列表,并且對于每一個列表:a)獲取它下面的<name> 元素。b)檢查該元素下的TEXT 節點。

          然而,該例是建立在一些簡單的假設之上的。它假設處理指令、注釋、CDATA節點和實體引用不能存在于數據結構中。許多簡單的應用程序能夠去掉這些假設。另外,真正強壯的應用程序需要處理各類有效的XML數據。

          (僅當輸入數據包含所需的簡化的XML結構時,“簡單”的應用程序才能運行。但是沒有任何驗證機制能夠確保不存在更加復雜的結構。畢竟,XML是專門為它們設計的。)

          要變得更加強壯,DOM API中的例子代碼必須完成以下事情:

          1. 搜索<name> 元素時:

          a.     忽略注釋、屬性和處理指令。

          b.     允許出現<coffee> 子元素沒有按指定的順序出現的情況。

          c.      如果沒有驗證,跳過包含可忽略空白的TEXT 節點。

          2. 提取節點的文本時:

          a.     CDATA 節點和文本節點提取文本。

          b.     收集文本時忽略注釋、屬性和處理指令。

          c.      如果遇到了實體引用節點或另一個元素節點,遞歸。(也就是說,將文本提取過程應用于所有的子節點)


          注意:JAXP 1.2解析器不將實體引用節點插入DOM。相反,它插入包含引用內容的TEXT 節點。另外,建立在1.4平臺中的JAXP 1.1解析器并不插入實體引用。所以,所以獨立于解析器的強壯的實現需要能處理實體引用節點。

          當然,許多應用程序不用擔心這類事情,因為它們看到的數據受到了嚴格的控制。如果數據能夠來自于各類外部源,應用程序就必須考慮這些可能性。

          DOM教程搜索節點 獲得節點內容的結尾處給出了執行這些函數的代碼。現在,目標就是確定DOM是不是適合于你的應用程序。

          選擇模型

          可以看到,使用DOM時,即便是像得到節點中的文本這樣簡單的操作也要進行大量的編碼。所以,如果程序將處理簡單數據結構,JDOMdom4j甚至1.4正則表達式包(java.util.regex)將更能滿足你的需求。

          另外,對于完備的文檔和復雜的應用程序,DOM 提供了大量靈活性。并且如果需要使用XML Schema,那么至少DOM是可以使用的方法。

          如果你要在開發的應用程序中處理文檔和數據,那么DOM可能仍然是最好的選擇。畢竟,一旦編寫了檢查和處理DOM結構的代碼,自定義它以實現特定的目的就很容易了。所以,選擇在DOM中完成所有的事情,只需要處理一個API集合而不是兩個。

          還有,DOM標準是標準的。它很強壯且完整,并且有許多實現。這是許多大型安裝的決定因素——特別是對產品應用程序,以避免在API發生改變時進行大量的改寫。

          最后,雖然目前不允許對通訊簿中的文本加粗、傾斜、設置顏色和改變字體大小,某一天可能還是需要處理這些。由于實際上DOM將處理你拋給它的所有內容,選擇DOM能夠更加容易生成“能適應未來(future-proof)”的應用程序。

          XML數據讀入到DOM

          本節將通過讀取現有XML文件來構建一個文檔對象模型 (DOM)。在下面幾節,你將會學習如何在Swing樹組件中顯示XML并且練習操作DOM


          注意:在教程的下一節轉換XML樣式表語言中,你將看到如何寫出作為XML文件的DOM(你也將看到如何相對簡單地將現有的數據文件轉換成XML)


          創建程序

          文檔對象模型(DOM)提供了創建節點、修改節點、刪除及重新組織它們的API。在本教程的第五節創建和操縱DOM中可以看到,創建DOM相對比較容易。

          然而,在創建DOM之前,要先了解DOM的結構。這系列練習通過在Swing Jtree中顯示DOM,以便能看到DOM的內部。

          創建框架

          既然已經對如何創建DOM有了大致了解,現在來建立一個簡單程序來將XML文檔讀入DOM,然后在回寫。


          注意:本節討論的代碼在DomEcho01.java中。它操作在文件 slideSample01.xml 上。(可瀏覽的版本是 slideSample01-xml.html)


          先來看看應用程序的基本邏輯,確保命令行上帶有一個參數:

          public class DomEcho {

            public static void main(String argv[])

            {

              if (argv.length != 1) {

                System.err.println(

                    "Usage: java DomEcho filename");

                System.exit(1);

              }

            }// main

          }// DomEcho

          導入所需的類

          本節中將看到所有的類都是單獨命名的。這樣,在引用API文檔時就能知道每個類的出處。在你自己的應用程序中,你可能希望使用短格式javax.xml.parsers.*來替換如下所示的導入語句。

          添加如下代碼以導入要使用的JAXP API

          import javax.xml.parsers.DocumentBuilder;

          import javax.xml.parsers.DocumentBuilderFactory;

          import javax.xml.parsers.FactoryConfigurationError;

          import javax.xml.parsers.ParserConfigurationException;

          想在解析XML文檔時拋出異常,添加下面幾行:

          import org.xml.sax.SAXException;

          import org.xml.sax.SAXParseException;

          添加下面幾行來讀取示例XML文件并識別錯誤:

          import java.io.File;

          import java.io.IOException;

          最后,為DOMDOM異常導入W3C定義:

          import org.w3c.dom.Document;

          import org.w3c.dom.DOMException;


          注意:僅在遍歷或操作DOM時才會拋出DOMException 。使用下面介紹的不同機制來報告解析過程中出現的錯誤。


          聲明 DOM

          org.w3c.dom.Document 類是文檔對象模型(DOM)的W3C名。不管解析XML文檔還是創建一個XML文檔,都會產生一個文檔實例。在教程的后面將在另一個方法中引用該對象,所以,在這里將它定義成全局對象:

          public class DomEcho

          {

            static Document document;

           

            public static void main(String argv[])

            {

          它必須是static的,因為你需要在很短時間內從main方法生成它的內容。

          處理錯誤

          下一步,插入錯誤處理邏輯。該邏輯基本上跟SAX教程的使用非驗證解析器處理錯誤中的代碼相同,所以在這里就不詳細介紹了。在這里要特別提醒的是,當解析XML文檔遇到困難時,需要JAXP-conformant 文檔構造器來報告SAX異常。實際上DOM解析器不需要在內部使用SAX解析器,但是由于早就有了SAX標準,看來可以用它來報告錯誤。結果,DOMSAX應用程序的錯誤處理代碼就非常簡單:

          public static void main(String argv[])

          {

            if (argv.length != 1) {

              ...

            }

           

            try {

           

          } catch (SAXParseException spe) {

            //

           Error generated by the parser

              System.out.println("\n** Parsing error"

                + ", line " + spe.getLineNumber()

                + ", uri " + spe.getSystemId());

              System.out.println("   " + spe.getMessage() );

            

              // Use the contained exception, if any

              Exception  x = spe;

              if (spe.getException() != null)

                x = spe.getException();

              x.printStackTrace();

           

            } catch (SAXException sxe) {

              //

           Error generated during parsing

              Exception  x = sxe;

              if (sxe.getException() != null)

                x = sxe.getException();

              x.printStackTrace();

           

             } catch (ParserConfigurationException pce) {

              // Parser with specified options can't be built

              pce.printStackTrace();

           

             } catch (IOException ioe) {

              // I/O error

              ioe.printStackTrace();

            }

           

          }// main

          實例化工廠

          接著,添加下面的代碼,得到工廠的一個實例,該實例能夠給出一個文檔構造器:

          public static void main(String argv[])

          {

            if (argv.length != 1) {

              ...

            }

            DocumentBuilderFactory factory =

              DocumentBuilderFactory.newInstance();

            try {

          獲得解析器并解析文件

          現在,添加下面的代碼以獲得構造器的一個實例,并用它來解析指定的文件:

          try {

            DocumentBuilder builder = factory.newDocumentBuilder();

            document = builder.parse( new File(argv[0]) );

          } catch (SAXParseException spe) {

          保存該文件!

          到現在,你可能覺得啟動每個JAXP應用程序的方法幾乎相同。的確如此!保存該版本的文件,將它作為模板。后面將要使用它,它是XSLT轉換應用程序的基礎。

          運行程序

          在整個DOM教程中,將使用SAX段中看到的示例幻燈片顯示。尤其是,你將使用slideSample01.xml它是一個簡單的XML文件,內部沒有什么內容)和slideSample10.xml(是一個更加復雜的例子,引入了DTD、處理指令、實體引用和CDATA段)。

          關于如何編譯并運行程序的說明,請查看SAX教程的編譯和運行程序 。以"DomEcho"替代"Echo"作為程序的名字。

          slideSample01.xml上運行該程序。如果運行沒有出錯,你就成功地解析了一個XML文檔并且構建了一個DOM。恭喜!


          注意:目前你只能聽從我的建議,因為這時你沒有任何辦法來顯示結果。但是在不久的將來...


          其他信息

          既然你已經成功地讀取了一個DOM,要高效使用DocumentBuilder 必須知道一到兩點。即:

          ·   配置Factory

          ·   處理驗證錯誤

          配置工廠

          默認情況下,工廠返回非驗證解析器,對命名空間一無所知。要獲得一個驗證解析器,并且/或能理解命名空間,請使用下面的命令來設置一個或多個參數,以配置該工廠:

          public static void main(String argv[])

          {

            if (argv.length != 1) {

              ...

            }

            DocumentBuilderFactory factory =

              DocumentBuilderFactory.newInstance();

            factory.setValidating(true);

            factory.setNamespaceAware(true);

            try {

              ...


          注意:不要求JAXP-conformant解析器支持這些參數的所有的結合,雖然引用解析器支持。如果你指定了一個無效的參數結合,在獲得解析器實例時factory產生ParserConfigurationException


          DOM教程的最后一節使用命名空間中將詳細介紹如何使用命名空間。本節要結束了,雖然你仍然希望知道

          處理驗證錯誤

          記住,在你閱讀SAX教程時,你所要做的事情就是構建一個DOM?這里,那些信息起作用了。

          記住對驗證錯誤的默認反應(由SAX標準提出)就是什么不也做。JAXP標準要求拋出SAX異常,所以使用跟SAX應用程序中幾乎相同的錯誤處理機制。尤其需要使用DocumentBuildersetErrorHandler方法提供實現SAX ErrorHandler 接口的對象。


          注意:也可以使用DocumentBuilder 中的setEntityResolver 方法。


          下面的代碼使用匿名內部類來定義ErrorHandler。下面的代碼確保驗證錯誤產生異常。

          builder.setErrorHandler(

            new org.xml.sax.ErrorHandler() {

              // ignore fatal errors (an exception is guaranteed)

              public void fatalError(SAXParseException exception)

              throws SAXException {

              }

              // treat validation errors as fatal

              public void error(SAXParseException e)

              throws SAXParseException

              {

                throw e;

              }

           

               // dump warnings too

              public void warning(SAXParseException err)

              throws SAXParseException

              {

                System.out.println("** Warning"

                  + ", line " + err.getLineNumber()

                  + ", uri " + err.getSystemId());

                System.out.println("   " + err.getMessage());

              }

            

          ); 

          本段代碼使用匿名內部類來產生實現ErrorHandler 接口的對象實例。由于它沒有類名字,所以是“匿名”的。你可以將它看作"ErrorHandler"實例,雖然技術上它是實現指定接口的沒有名字的實例。這些代碼本質上跟使用非驗證解析器處理錯誤中的相同。要了解驗證問題的更多知識,請參照使用驗證解析器

          展望未來

          下節中將在Jtree中顯示DOM結構,并且開始展示它的結構。例如,你將看到實體引用和CDATA段是如何出現在DOM中的。可能更加重要的是,你將看到如何將文本節點(它包含實際的數據)放在DOM中的元素節點下。

          顯示DOM層次結構

          要創建或操縱一個文檔對象層次結構 (DOM),必須要清楚地了解DOM中節點的結構。本節中將展示DOM的內部結構。

          回送樹節點

          現在你所需要的是展示DOM中節點的方法,這樣你就能看到節點內究竟包含什么。要實現這一點,將DOM轉換成JTreeModel 并且在Jtree中顯示完整的DOM。這些需要大量的工作,但是它不僅將產生你將來要使用的診斷工具,而且可以幫助你了解DOM結構。

          DomEcho 轉換為GUI 應用程序

          由于DOM是樹,并且Swing JTree 組件都跟顯示樹有關,所以有必要將DOM放入Jtree,以便查看。該過程的第一步是處理DomEcho 程序,讓它成為一個GUI 應用程序。

          注意:本節討論的代碼在DomEcho02.java中。

          添加Import語句

          首先導入建立應用程序和顯示Jtree需要的GUI組件:

          // GUI components and layouts

          import javax.swing.JFrame;

          import javax.swing.JPanel;

          import javax.swing.JScrollPane;

          import javax.swing.JTree;  

          DOM教程的后面部分將設計DOM顯示,以產生Jtree顯示的用戶友好版本。用戶選擇樹中的元素時,子元素將顯示在鄰近的編輯器面板中。所以,進行安裝工作時,需要導入建立分割視圖(JSplitPane)和顯示子元素文本(JEditorPane)所需的組件:

          import javax.swing.JSplitPane;

          import javax.swing.JEditorPane; 

          添加一些你需要的支持類:

          // GUI support classes

          import java.awt.BorderLayout;

          import java.awt.Dimension;

          import java.awt.Toolkit;

          import java.awt.event.WindowEvent;

          import java.awt.event.WindowAdapter; 

          最后,導入一些類來建立別致的邊框:

          // For creating borders

          import javax.swing.border.EmptyBorder;

          import javax.swing.border.BevelBorder;

          import javax.swing.border.CompoundBorder; 

          (這些是可選的。如果想要簡化代碼,可以跳過它們以及相關代碼。)

          創建GUI框架

          下一步是將應用程序轉換為GUI應用程序。為此,靜態main方法將創建main類的一個實例,它將成為GUI面板。

          首先擴展Swing JPanel 類,將該類變成一個GUI面板:

          public class DomEcho02 extends JPanel

          {

            // Global value so it can be ref'd by the tree-adapter

            static Document document;

            ...

          定義一些用來控制窗口大小的常量:

          public class DomEcho02 extends JPanel

          {

            // Global value so it can be ref'd by the tree-adapter

            static Document document; 

            static final int windowHeight = 460;

            static final int leftWidth = 300;

            static final int rightWidth = 340;

            static final int windowWidth = leftWidth + rightWidth; 

          現在,在main方法中,調用創建GUI面板所在的外部框架的方法:

          public static void main(String argv[])

          {

            ...

            DocumentBuilderFactory factory ...

            try {

              DocumentBuilder builder = factory.newDocumentBuilder();

              document = builder.parse( new File(argv[0]) );

              makeFrame();

               } catch (SAXParseException spe) {

              ...

          然后,需要定義makeFrame方法本身。它包含創建框架的標準代碼,并能很好地處理退出條件,給出main面板的實例,定制它的大小,最后將其定位于屏幕上并使之可視化:

             ...

          } // main

          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

          添加顯示組件

          將程序轉換成GUI應用程序的工作只剩下創建類構造函數并讓它創建面板的內容。下面是構造函數:

          public class DomEcho02 extends JPanel

          {

            ...

            static final int windowWidth = leftWidth + rightWidth;

            

            public DomEcho02()

            {

            } // Constructor

          這里,使用前面導入的邊框類建立常用邊框(可選)

          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));

           

          } // Constructor

          然后,創建一棵空樹并且將它放入JScrollPane ,這樣當它變大時,用戶就能看到它的內容:

          public DomEcho02(

          {

            ...

           

            //

           Set up the tree

            JTree tree = new JTree();

           

            // Build left-side view

            JScrollPane treeView = new JScrollPane(tree);

            treeView.setPreferredSize(

              new Dimension( leftWidth, windowHeight ));

           

          } // Constructor

          現在,創建不可編輯的JEditPane ,它將最終保存選中的JTree 節點指向的內容:

          public DomEcho02(

          {

            ....

           

            // Build right-side view

            JEditorPane htmlPane = new JEditorPane("text/html","");

            htmlPane.setEditable(false);

            JScrollPane htmlView = new JScrollPane(htmlPane);

            htmlView.setPreferredSize(

              new Dimension( rightWidth, windowHeight ));

           

          }  // Constructor

          構建了左邊的JTree 和右邊的JEditorPane 后,創建一個JSplitPane 來存放它們:

          public DomEcho02()

          {

            ....

           

            // 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 ));

           

          }  // Constructor

          該代碼建立了帶有垂直分割線的JSplitPane 。它將在樹和編輯器面板之間產生“水平分割線”。(實際上,更是水平布局)你也要設置分割線的位置,這樣樹能夠得到它要的寬度,將剩下的窗口寬度分配給編輯器面板。

          最后,指定面板的布局并且添加split pane

          public DomEcho02()

          {

            ...

           

            // Add GUI components

            this.setLayout(new BorderLayout());

            this.add("Center", splitPane );

           

          } // Constructor

          恭喜!該程序現在是一個GUI應用程序。現在可以運行它,看看屏幕上的總體布局是怎樣的。為了引用,這里有完整的構造函數:

          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

          創建適配器以便在Jtree中顯示DOM

          現在已經有一個GUI框架來顯示JTree ,下一步是獲得Jtree顯示DOM。但是JTree 希望顯示TreeModel DOM 是樹,但它不是TreeModel。所以需要創建一個適配器使得DOM

          posted on 2005-03-23 15:18 閱讀(276) 評論(0)  編輯  收藏 所屬分類: Java_Xml

          主站蜘蛛池模板: 宁津县| 莆田市| 银川市| 景泰县| 启东市| 清苑县| 恩施市| 年辖:市辖区| 西安市| 苏尼特右旗| 怀集县| 吴忠市| 改则县| 广汉市| 托克逊县| 读书| 北辰区| 根河市| 古交市| 金川县| 泌阳县| 同江市| 平山县| 翁源县| 五莲县| 阿拉善左旗| 南华县| 河南省| 江孜县| 穆棱市| 临夏市| 连城县| 保山市| 兴和县| 如东县| 宝山区| 吴川市| 德格县| 礼泉县| 普安县| 个旧市|