选择显示字体大小

使用java swing 创建一个xml编辑器

出自:yesky

我想您一定对xml有所了解,说不定您现在还跃跃欲试想写一段xml文本呢,可是现在能找到的跨平台的、免费的xml编辑器太少了。所以在本文中,我想介绍一下或者说带您一步一步的开发一个简单的xml编辑器,当然我们要用到一些最常见的java 2 swing组件,不过这些都是免费的,有些是jdk中的,有些是可以从网上下载的。我想通过本文,你就可以创建一个属于你自己的xml编辑器。

  先让我介绍一下本文辑写的思路。首先我想简要的讨论一下xml和为什么树型结构比较适合用来显示xml,然后我们来看一看jaxp api如何建立所需要的xml类的环境;然后我们将了解用来显示一个图形树的jtree swing组件;最后,我们将创建一个继承jtree组件的可以重复使用的类,可以用来分析一个xml文档,并把数据显示在一个jtree中。

  说到xml(extensible markup languge),人们往往把它当成是一种新的用于web浏览器中的标记语言,就象htmlcss一样。其实,xml是一种数据表示语言,它允许你使用一种非常有效的方法来描述你的数据。xml能够使你定义诸如“these three words constitutes a heading”这样的语句。xml允许你声明任何类型的数据,而不是用来把这些数据显示在网页中。

  请看一看下面的xml实例:

<article>
<header>
<title> 使用java swing 创建一个xml编辑器
<subtitle> 第一部分</subtitle>
</title>
<author> wayne </author>
<header>
<content> 这是正文</content>
</article>


  请注意,这些元素和标准的html语句是不同的,但是它们看上去比较象html,这是因为xmlhtml都是来源于sgml语言。不同的是html有预定义的标签集,而xml的语法则有许多灵活性,它允许你使用表意的标记如<author>来括在数据两边。你还要注意,所有的元素都从属于根元素(上例中为<article>),有些元素则还有自己的子元素,如<subtitle>就是<title>的子元素。这样的数据组织方式有三个好处:数据能够更加表意,数据更加易维护而且数据更加容易作为一个树的结构表现出来,这就是我们为什么使用jtree对象来显示xml数据的原因。如果你想对xml有更深的了解,请参阅天极网上的相关教程。

  jaxp是一个用于处理xmljava api,它能够使应用程序分析并且转化xml文档,它的功能有点象jdbc api,都是把函数功能抽象成一个个方法。你可以去apache网站找到最新的xerces分析器,其中含有最新的jaxp,下载下来以后把它放在你的类目录中。

下面让我们看一下如何使用jtree swing组件。

  我们都知道,在自然界中,一棵树通常都有一个非常粗的树干,树干上有许多树枝分叉。每个树杈和树杈之间都有一定的联系,因为它们都有同一个来源:树干。这种继承的关系并不只在树枝中有,人类谱系也遵循相同的规律。从父母,到子女再到子女的子女,就这样直到数不清为止。同样,在数据存储中,树的概念也是一种使用同人类家谱树一样方法储存数据的方法。树的每一个树杈称为一个节点,每个有子节点的节点称为父节点,所有的子节点的公共的父节点被称为根节点。一个jtree组件就是一个简单的树数据结构的可视化表现形式。

  几乎所有的xml编辑器都包括一个可视化的树结构,能让你编辑xml文档中的元素。我们马上就会构建一个编辑器,不过在此之前,先让我们再了解一下jtree组件。一个节点在一棵树的某个位置储存数据,为了存储数据,必须知道任何一个父节点和它们的子节点。javax.swing.tree包定义了一些非常有用的接口,提供了一种通用的方法构建和操作一个树结构。

  treenode方法,用于访问树的节点的信息

  mutabletreenode方法 用在一个可变的树上(能够添加或删除子节点)

  treemodel方法 用于创建和管理与树有关的数据模型。

  接下来,我们将创建一个继承jtree的类,提供分析xml文档和用可视化jtree组件把节点显示出来的功能。

  创建xtree组件

  xtree类由一个构造函数和三个方法组成,为了简单起见我们的组件只能构建一个xtree,在树创建好之后不能进行处理它的节点。下面让我们来看一个这个类。

  域:

  private defaultmutabletreenode treenode 这个成员变量储存treenode对象用于存储jtree的模型。 

  defaultmutabletreenode类是在javax.swing.tree中被定义的,默认提供了mutabletreenode接口的一个实现。

  private documentbuilderfactory dbf

  private documentbuilder db

  private document doc 这三个成员变量是jaxp的一部分,用来分析xml文本并转化成dom(document object model) 对象。

  构造函数

  public xtree( string text )

  这个构造函数通过使用传送到构造器中的xml文本创建一个xtree对象。在初始化一些与jtree超类和dom分析对象有关的基本显示属性后,构造函数生成一个treemodel 对象用来创建一个实际可视的树。通过把dom对象传送到createtreenode()方法来创建一个根节点,createtreenode()方法返回一个defaultmutabletreenode类型的对象。这个对象然后被用来创建树的treemodel。

  方法

   private defaultmutabletreenode createtreenode( node root )

  这个方法采用一个dom 节点,然后在子节点中递归直到所有的接点都被添加到defaultmutabletreenode中。这是一个递归方法,为了找到根节点下的每一个子节点,它每次都要调用自己。jtree然后就可以使用defaultmutabletreenode对象了,因为它已经是树型了。

   private string getnodetype( node node )

  这个方法,被createtreenode()用来联系一个字符串和某一种类型的节点。

   private node parsexml()

  这个方法,用来分析xml文本字符串,它返回node类型的对象,能够被传送到createtreenode()方法中。
下面我给出了java代码,供大家分析研究。

// 到入w3c的dom 类
import org.w3c.dom.*;
// jaxp的用于dom i/o的类
import javax.xml.parsers.*;
// 标准java
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class xtree extends jtree
{
/**
* 这个成员变量储存treenode对象用于存储jtree的模型。
*defaultmutabletreenode类是在javax.swing.tree中被定义的
*默认提供了mutabletreenode接口的一个实现。
*/
private defaultmutabletreenode treenode;
/**
* 这三个成员变量是jaxp的一部分,用来分析xml文本并转化成dom(document object model) 对象。
*/
private documentbuilderfactory dbf;
private documentbuilder db;
private document doc;

 /**
 * 这个构造函数通过使用传送到构造器中的xml文本创建一个xtree对象

 * @参数 text是一个xml格式的xml文本

 * @异常 parserconfigurationexception 如果构造函数非正常的设置分析器,就会抛出异常

 */

public xtree( string text ) throws parserconfigurationexception
{
super();

// 设置tree渲染的基本属性
getselectionmodel().setselectionmode( treeselectionmodel.single_tree_selection );
setshowsroothandles( true );
seteditable( false ); // 允许树可以编辑

// 通过初始化对象的dom来分析对象
dbf = documentbuilderfactory.newinstance();
dbf.setvalidating( false );
db = dbf.newdocumentbuilder();

// 采用dom根节点并且把它转化成jtree的树模型
treenode = createtreenode( parsexml( text ) );
setmodel( new defaulttreemodel( treenode ) );
} file://中止xtree()


  /**

  * 这个方法采用一个dom 节点,然后在子节点中递归直到所有的接点都被添加到defaultmutabletreenode中。

  * 这是一个递归方法,为了找到根节点下的每一个子节点,它每次都要调用自己。

  * jtree然后就可以使用defaultmutabletreenode对象了,因为它已经是树型了。

  *

  * @参数 root org.w3c.node.node

  *

  * @返回值 返回一个基于根节点defaultmutabletreenode对象

  */

private defaultmutabletreenode createtreenode( node root )
{
defaultmutabletreenode treenode = null;
string type, name, value;
namednodemap attribs;
node attribnode;

// 从根节点中取得数据
type = getnodetype( root );
name = root.getnodename();
value = root.getnodevalue();

treenode = new defaultmutabletreenode( root.getnodetype() == node.text_node ? value : name );

// 显示属性
attribs = root.getattributes();
if( attribs != null )
{
for( int i = 0; i < attribs.getlength(); i++ )
{
attribnode = attribs.item(i);
name = attribnode.getnodename().trim();
value = attribnode.getnodevalue().trim();

if ( value != null )
{
if ( value.length() > 0 )
{
treenode.add( new defaultmutabletreenode( "[attribute] --> " + name + "=\"" + value + "\"" ) );
} file://end if ( value.length() > 0 )
} file://end if ( value != null )
} file://end for( int i = 0; i < attribs.getlength(); i++ )
} file://end if( attribs != null )

// 如果存在子节点,递归
if( root.haschildnodes() )
{
nodelist children;
int numchildren;
node node;
string data;

children = root.getchildnodes();
// 如果子节点非空的话,只递归
if( children != null )
{
numchildren = children.getlength();

for (int i=0; i < numchildren; i++)
{
node = children.item(i);
if( node != null )
{
if( node.getnodetype() == node.element_node )
{
treenode.add( createtreenode(node) );
} file://end if( node.getnodetype() == node.element_node )

data = node.getnodevalue();

if( data != null )
{
data = data.trim();
if ( !data.equals("\n") && !data.equals("\r\n") && data.length() > 0 )
{
treenode.add(createtreenode(node));
} file://end if ( !data.equals("\n") && !data.equals("\r\n") && data.length() > 0 )
} file://end if( data != null )
} file://end if( node != null )
} file://end for (int i=0; i < numchildren; i++)
} file://end if( children != null )
} file://end if( root.haschildnodes() )
return treenode;
} file://end createtreenode( node root )


  /**

  * 这个方法,被createtreenode()用来联系一个字符串和某一种类型的节点。

  *

  * @参数 node org.w3c.node.node

  *

  * @返回值 返回显示节点类的字符串

  */

private string getnodetype( node node )
{
string type;

switch( node.getnodetype() )
{
case node.element_node:
{
type = "element";
break;
}
case node.attribute_node:
{
type = "attribute";
break;
}
case node.text_node:
{
type = "text";
break;
}
case node.cdata_section_node:
{
type = "cdata section";
break;
}
case node.entity_reference_node:
{
type = "entity reference";
break;
}
case node.entity_node:
{
type = "entity";
break;
}
case node.processing_instruction_node:
{
type = "processing instruction";
break;
}
case node.comment_node:
{
type = "comment";
break;
}
case node.document_node:
{
type = "document";
break;
}
case node.document_type_node:
{
type = "document type";
break;
}
case node.document_fragment_node:
{
type = "document fragment";
break;
}
case node.notation_node:
{
type = "notation";
break;
}
default:
{
type = "???";
break;
}
}// 结束 switch( node.getnodetype() )
return type;
} file://结束 getnodetype()


  /**

  * 这个方法,用来分析xml文本字符串,它返回node类型的对象,能够被传送到createtreenode()方法中。

  *

  * @参数 text 一个显示xml文档的字符串

  * @返回值 返回一个org.w3c.node.node对象

  */

private node parsexml( string text )
{
bytearrayinputstream bytestream;

bytestream = new bytearrayinputstream( text.getbytes() );

try
{
doc = db.parse( bytestream );
}
catch ( exception e )
{
e.printstacktrace();
system.exit(0);
}
return ( node )doc.getdocumentelement();
} file://结束 parsexml()

} file://结束 class xtree





  代码2 xtreetester.java

import javax.xml.parsers.*;

// gui
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

file://标准 java
import java.io.*;


public class xtreetester extends jframe
{
// xtree对象,用来在jtree中显示xml
private xtree xtree;
// jscrollpane是jtree的容器
private jscrollpane jscroll;
private windowlistener winclosing;

// 设置框架的宽和高
private static final int frame_width = 400;
private static final int frame_height = 300;


  /*

  * 构造器构造一个框架包含jscrollpane,

  * 把一个基于xml字符串的xtree对象传到构造函数中

  */

public xtreetester( string title, string xml ) throws parserconfigurationexception
{
super( title );

toolkit toolkit;
dimension dim, minimumsize;
int screenheight, screenwidth;

// 初始化基本的布局属性
setbackground( color.lightgray );
getcontentpane().setlayout( new borderlayout() );
toolkit = toolkit.getdefaulttoolkit();
dim = toolkit.getscreensize();
screenheight = dim.height;
screenwidth = dim.width;
setbounds( (screenwidth-frame_width)/2, (screenheight-frame_height)/2, frame_width, frame_height );

// 构建xtree对象
xtree = new xtree( xml );

file://把xtree封装到jscroll中,以便在jframe可以使它在屏幕中上下滚动.
jscroll = new jscrollpane();
jscroll.getviewport().add( xtree );

// 添加滚动条到框架
getcontentpane().add( jscroll, borderlayout.center );
validate();
setvisible(true);
// 添加windowlistener用来关闭窗口
winclosing = new windowadapter()
{
public void windowclosing(windowevent e)
{
exit();
}
};
addwindowlistener(winclosing);
}


  // 程序从这里开始执行。必须把一个以xml为扩展名的xml文件传送到这个方法中,其格式为java xtreetester yourxmlfilename.xml

public static void main( string[] args )
{
string filename = "";
bufferedreader reader;
string line;
stringbuffer xmltext;
xtreetester xtreetester;

// 创建一个基于特定xml文件的文档对象
try
{
if( args.length > 0 )
{
filename = args[0];

if ( filename.substring( filename.indexof( '.' ) ).equals( ".xml" ) )
{
reader = new bufferedreader( new filereader( filename ) );
xmltext = new stringbuffer();

while ( ( line = reader.readline() ) != null )
{
xmltext.append( line );
}

// 分析完文档对象后将重写文件
reader.close();

// 构造 gui 组件
xtreetester = new xtreetester( "xtree 测试", xmltext.tostring() );
}
else
{
help();
}
}
else
{
help();
}
}
catch( filenotfoundexception fnfex )
{
system.out.println( "没有发现"+ filename + "文件。" );
exit();
}
catch( exception ex )
{
ex.printstacktrace();
exit();
}
}


  file://帮助信息

private static void help()
{
system.out.println( "\n使用方法:java xtreetester yourxmlfilename.xml" );
system.exit(0);
}

// 退出
private static void exit()
{
system.out.println( "\n谢谢使用 xtree" );
system.exit(0);
}

}


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons