分享
 
 
 

使用Java Swing 创建一个XML编辑器(一)

王朝java/jsp·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

www.dukeJava.com 网络娇娃工作站

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

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

说到XML(eXtensible Markup Languge),人们往往把它当成是一种新的用于Web浏览器中的标记语言,就象Html或Css一样。其实,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,这是因为XML和HTML都是来源于SGML语言。不同的是HTML有预定义的标签集,而XML的语法则有许多灵活性,它答应你使用表意的标记如<author>来括在数据两边。你还要注重,所有的元素都从属于根元素(上例中为<article>),有些元素则还有自己的子元素,如<subtitle>就是<title>的子元素。这样的数据组织方式有三个好处:数据能够更加表意,数据更加易维护而且数据更加轻易作为一个树的结构表现出来,这就是我们为什么使用JTree对象来显示XML数据的原因。假如你想对XML有更深的了解,请参阅天极网上的相关教程。

JAXP是一个用于处理XML的Java 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("

") && !data.equals("

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有