程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用Java Swing創建一個XML編輯器之二

使用Java Swing創建一個XML編輯器之二

編輯:關於JAVA

這是本系列的第二篇文章。在上一篇文章中,我們簡要地討論了XML以及為什麼一個樹形結構適合顯示XML、如何處理XML數據、如何使用JTree Swing 組件以及如何創建一個可重用的能夠分析XML文檔以及在Jtree顯示數據的組件。

在本文中,我們將創建我們的XML編輯器的框架,為了達到這個目的,我們將用到許多Swing組件(包括JsplitPane、JscrollPane、Jbutton和JtextArea組件)。

一、問題的提出與解決

我如何創建一個能夠浏覽文本和浏覽視圖的XML文本編輯器呢?創建一個包含Jbutton和JsplitPane的Jframe對象, 然後讓JsplitPane對象包含兩個JscrollPane對象,一個用於浏覽圖形(xTree類),另一個用於浏覽文本(JtextArea類)。Jbutton用來管理刷新圖形浏覽的操作。

二、增強Xtree類的功能

在上一篇文章中,我們開發了Xtree類,這是一個可重用的組件,繼承於Jtree類並能夠把XML數據以圖形樹的形式顯示。我們現在就增強這個類, 通過提供給它一個在顯示默認的XML樹來We will now enhance that class by providing it with a default XML tree to display in the event that an XML file is not supplied at the command-line. 而且,我們還將添加一些錯誤處理邏輯以便程序不會因為無效的XML而崩潰。

第一步是創建一個名為buildTree()的方法:

private DefaultTreeModel buildTree( String text )
{
  DefaultMutableTreeNode treeNode;
  Node newNode;
  // 采用DOM根節點並把它轉化成為一個Tree模型
  newNode = parseXml( text );
  if ( newNode != null )
  {
   treeNode = createTreeNode( newNode );
   return new DefaultTreeModel( treeNode );
  }
  else
   return null;
  } file://結束buildTree()

這個方法取得傳入的 XML字符串,分析這個 XML字符串並構造一個可以用來從數據中構造圖形樹形結構的DefaultTreeModel變量實例。這個功能原來包含在 XTree()構造程序中,但是我們把它拿出來然後把它放進一個單獨的方法中,這樣我們就有了創建一個默認圖形樹的伸縮性。這就是我們接下來想做的事。

接下來一步是創建一個叫 buildWelcomeTree()的方法。這個方法一次構建一個DefaultTreeModel變量,而不是通過分析一個現有的XML文字字符串。如果用戶沒有指定 XML文件就啟動這個應用程序,將顯示 DefaultTreeModel。見代碼段1

代碼段1:

private DefaultTreeModel buildWelcomeTree()
{
  DefaultMutableTreeNode root;
  DefaultMutableTreeNode instructions, openingDoc,
             editingDoc, savingDoc;
  DefaultMutableTreeNode openingDocText, editingDocText,
             savingDocText;
  DefaultMutableTreeNode development, addingFeatures,
             contactingKyle;
  root = new DefaultMutableTreeNode( "Welcome to XML View 1.0" );
  instructions = new DefaultMutableTreeNode( "Instructions" );
  openingDoc = new DefaultMutableTreeNode
              ( "Opening XML Documents" );
  openingDocText = new DefaultMutableTreeNode
              ( "When invoking the XmlEditor from
  the command-line, you must specify the filename." );
  editingDoc = new DefaultMutableTreeNode
              ( "Editing an XML Document" );
  editingDocText = new DefaultMutableTreeNode
              ( "XML text in the right hand frame
              can be edited directly.
              The \"refresh\" button will rebuild
              the JTree in the left frame." );
  savingDoc = new DefaultMutableTreeNode
              ( "Saving an XML Document" );
  savingDocText = new DefaultMutableTreeNode
             ( "This iteration of the XmlEditor does
               not provide the ability to save your
               document. That will come with the
               next article." );
  root.add( instructions );
  instructions.add( openingDoc );
  instructions.add( editingDoc );
  openingDoc.add( openingDocText );
  editingDoc.add( editingDocText );
  return new DefaultTreeModel( root );
}

接下來的我們需要添加一個新的構造程序來簡化默認顯示功能,我們將修改主構造程序,這樣它就不能接受任何參數,創建一個新的能接收單一的 XML文本字符串的構造程序。這樣以來,如果沒有 XML文本被顯示的話就會創建默認 XTree對象,而如果 XML文本被顯示的話將創建一個唯一的 XTree對象。代碼段2中給出了兩個構造程序。

代碼段2:

public XTree( String text ) throws ParserConfigurationException
{
  this();
  refresh( text );
  }
public XTree() throws ParserConfigurationException
{
  super();
  getSelectionModel().setSelectionMode(
      TreeSelectionModel.SINGLE_TREE_SELECTION );
  setShowsRootHandles( true );
  setEditable( false );
  dbf = DocumentBuilderFactory.newInstance();
  dbf.setValidating( false );
  db = dbf.newDocumentBuilder();
  setModel( buildWelcomeTree() );
}

三、創建 XmlEditor類

XmlEditor類與前面的那篇文章的XTreeTester類有相同的用途,不同之處在於 XmlEditor包括一個 JTextArea,允許你操作文本版XML。之後,你可以點擊 “Refresh”按鈕並查看 XTree組件中反映出來的變化。

如果直接修改第一篇文章中的代碼,你就能節省很多時間,你可以把 XTreeTester.java文件重命名為 XmlEditor.java (不過一定要修改構造程序 )並把它當成模板文件。

要做的第一件事是添加下列 Swing組件:另一個 JScrollPane、 JSplitPane、 JTextArea和 JButton。通過聲明所有的這些組件以及其他組件開始(看代碼段3)。

代碼段3:

private XTree xTree;
private JScrollPane jScroll, jScrollRt;
private JSplitPane splitPane;
private JButton refreshButton;
private WindowListener winClosing;

首先,我們將創建並添加“ Refresh”按鈕。這個按鈕用來指示這個 XTree組件將使用當前 XML文本來刷新。我們還需要使用一個ActionListener來注冊它。(參見代碼段 4 ) 為了攔截按鈕事件,我們需要有這個類還要實現 ActionListener,而且我們還需要創建一個 actionPerformed()方法 (參見代碼段 5 )。

代碼段4:

refreshButton = new JButton( "Refresh" );
refreshButton.setBorder(
   BorderFactory.createRaisedBevelBorder() );
refreshButton.addActionListener( this );
getContentPane().add( refreshButton, BorderLayout.NORTH );

代碼段5:

public void actionPerformed( ActionEvent ae )
{
  if ( ae.getActionCommand().equals( "Refresh" ) )
   xTree.refresh( textArea.getText() );
}

接下來,我們將創建新的 JScrollPane和 JTextArea並且把 JTextArea添加到 JScrollPane中。這樣,我們將得到包含 XTree組件的原始的 JScrollPane和包含 JTextArea組件的新的 JScrollPane。這個原始的 XTree構造程序還有一個修改之處。我們將刪除先前傳進這個方法的字符串參數。(該功能通過我們接下來要構建的另一個 XmlEditor()構造程序操作)我們把這兩個方框放進一個 JSplitPane中,它是一個有分隔器的組件,可以在這個分隔器的另一邊包含一個組件。(參見代碼段6)。

代碼段6:

jScroll = new JScrollPane();
jScrollRt = new JScrollPane();
textArea = new JTextArea( 200,150 );
jScrollRt.getViewport().add( textArea );
xTree = new XTree();
xTree.getSelectionModel().setSelectionMode(
    TreeSelectionModel.SINGLE_TREE_SELECTION );
xTree.setShowsRootHandles( true );
xTree.setEditable( false );
jScroll.getViewport().add( xTree );
splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT,
    jScroll, jScrollRt );
splitPane.setOneTouchExpandable(true);
splitPane.setDividerLocation(200);
minimumSize = new Dimension(200, 150);
jScroll.setMinimumSize( minimumSize );
jScrollRt.setMinimumSize( minimumSize );
splitPane.setPreferredSize( new Dimension(400, 300) );
getContentPane().add( splitPane, BorderLayout.CENTER );

現在我們需要修改這個構造程序來處理這個非 XML文件的情景。刪除當前構造程序需要的第二個字符串參數。這個構造程序現在就是默認的構造程序。我們將創建一個新的構造程序來接收一個字符串參數。它將先調用默認構造程序,然後處理這個參數。(參見代碼段7 )而且,main()方法必須被修改以便在沒有XML文件的事件中,仍然能創建一個默認的XmlEditor對象。(參見代碼段8)

代碼段7:

public XmlEditor( String title, ArrayList xmlText ) throws
ParserConfigurationException
{
  this( title );
  textArea.setText( ( String )xmlText.get( 0 ) + "\n" );
  for ( int i = 1; i < xmlText.size(); i++ )
   textArea.append( ( String )xmlText.get( i ) + "\n" );
   xTree.refresh( textArea.getText() );
}

代碼段8:

public static void main( String[] args )
{
String fileName = "";
BufferedReader reader;
String line;
ArrayList xmlText = null;
XmlEditor xmlEditor;
try
{
if( args.length > 0 )
{
fileName = args[0];
if ( fileName.substring( fileName.indexOf( '.' ) ).equals( ".xml" ) )
{
reader = new BufferedReader( new FileReader( fileName ) );
xmlText = new ArrayList();
while ( ( line = reader.readLine() ) != null )
{
xmlText.add( line );
}
reader.close();
xmlEditor = new XmlEditor( "XmlEditor 1.0", xmlText );
}
else
{
help();
}
}
else
{
xmlEditor = new XmlEditor( "XmlEditor 1.0" );
}
}
catch( FileNotFoundException fnfEx )
{
System.out.println( fileName + " was not found." );
exit();
}
catch( Exception ex )
{
ex.printStackTrace();
exit();
}
}

為了很容易地處理 JTextArea數據,還需要最後一次必要的修改。一般我們不把這段文本當成一個長的字符串,而是把它當成一系列字符串,每行表示一個包含在數組列表中的字符串。這需要修改我們的構造程序接收的參數,並且修改在先前把這個數據作為一個字符串傳入的那個main()方法中的任何調用。這還需要導入 java.util包 (參見代碼段8 ) 。

測試這個應用程序

最後,我們必須添加一些異常處理到 XTree類中。如果你運行這個應用程序並輸入無效的XML數據到 JTextArea中,這個程序就會崩潰。我們當然不想這樣的事情發生。目前,我們把出錯信息打印到命令行中。在下一篇文章中,我們將在一個圖形對話框中顯示出錯信息。

如果無效的或格式不好的 XML數據被輸入 JTextArea然後按“Refresh”按鈕,然後解析器將拋出一個錯誤,在本例中,parseXML()方法中包含的當前異常處理將立即退出。我們想要這個程序報告這個錯誤並返回一個空值來指出這個解析是不成功的。(見代碼段9)你可能注意到 XTree類中的“buildTree()”和“refresh()”這兩個方法有一個條件語句以避免處理空值。這是因為如果它們試著去處理一個空值它們也會報告異常。這個事件鏈保持程序流進行並且保持 XTree模型穩定。

最後,我們就可以測試這個應用程序,測試過程我在這裡就不多說了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved