上一篇 / 下一篇 2005-05-22 07:36:00 / 个人分类:j2se
nny.wang / 2006-08-15 16:53:00
-
我想请教个问题,如何在:
public void treeWillExpand(TreeExpansionEvent me){
}
-
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.sql.*;
import java.io.*;
import java.util.*;
//
class Console
{
public static String title(Object o)
{
String t=o.getClass().toString();
if(t.indexOf("class") != -1)
t=t.substring(6);
return t;
}
public static void setupClosing(JFrame frame)
{
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
public static void run(JFrame frame,int width,int height)
{
setupClosing(frame);
frame.setSize(width,height);
frame.setVisible(true);
}
public static void run(JApplet applet,int width,int height)
{
JFrame frame=new JFrame(title(applet));
setupClosing(frame);
frame.getContentPane().add(applet);
frame.setSize(width,height);
applet.init();
applet.start();
frame.setVisible(true);
}
public static void run(JPanel panel,int width,int height)
{
JFrame frame=new JFrame(title(panel));
setupClosing(frame);
frame.getContentPane().add(panel);
frame.setSize(width,height);
frame.setVisible(true);
}
}
//
//================================================
class MytreeNode extends DefaultMutableTreeNode
{
String mydata,mylable;
MytreeNode(String ss)
{
super(ss);
}
public void setMydata(String s_mydata)
{
mydata=s_mydata;
}
public String getMydata()
{
return mydata;
}
public void setMylable(String s_mydata)
{
mylable=s_mydata;
}
public String getMylable()
{
return mylable;
}
}
//===============================================
public class Trees_test extends JApplet implements TreeModelListener
{
JTree tree;
public void init()
{
String url="jdbcdbc:ypower";
String user="ypower";
String pass="ypower";
String table="lineway";
String index="id";
String parent="parentid";
String lable="simname";
cjqTree ttt=new cjqTree(url,user,pass,table,index,parent,lable);
try
{
tree=(JTree)ttt.getTree();
}catch(ClassNotFoundException e){System.out.println("加载数据库驱动程序的时候出了错误!");}
catch(InstantiationException e){System.out.println("InstantiationException");}
catch(IllegalAccessException e){System.out.println("IllegalAccessException");}
catch(SQLException e){System.out.println("SQLException");System.exit(0);}
//树可以滚动
Container cp=getContentPane();
cp.add(new JScrollPane(tree),BorderLayout.CENTER);
}
public static void main(String[] args)
{
Console.run(new Trees_test(),500,500);
}
//实现TreeModelListener提供的接口///
//Void treeNodesChanged(TreeModelEvent e):当节点改变时系统就会云调用这个方法。/
//Void treeNodesInserted(TreeModelEvent e):当新增节时系统就会去调用这个方法。//
//Void treeNodesRemoved(TreeModeEvent e):当删除节点时系统就会去调用这个方法。//
//Void treeStructureChanged(TreeModelEvent e):当树结构改变时系统就会去调用这个方法。///
public void treeNodesInserted(TreeModelEvent e)
{//当增加新节点的时候返回当前节点的所有的子节点
}
public void treeNodesChanged(TreeModelEvent e)
{
}
public void treeNodesRemoved(TreeModelEvent e)
{
}
public void treeStructureChanged(TreeModelEvent e)
{
}
/
//TreeModelEvent方法: /
//int[] getChildIndices():返回子节点群的索引值。 /
//Object[] getChildren():返回子节点群.
//Object[] getPath():返回Tree中一条path上(从root nod到leaf node)的节点。/
//TreePath getTreePath():取得目前位置的Tree Path. /
//String toString():取得蝗字符串表示法. /
/
}
//====================================================================
class cjqTree
{
private
JTree mytree;
DefaultTreeModel mymodel;
Connection conn;
Statement myst;
String mysql;
ResultSet myresult;
String myurl,myuser,mypass,mytable,myindex,myparent,mylable;
cjqTree(String url,String user,String pass,String table,String index,String parent,String lable)
{
myurl=url;
myuser=user;
mypass=pass;
mytable=table;
myindex =index;
myparent=parent;
mylable=lable;
}
public JTree getTree() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException,
SQLException
{
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}catch(ClassNotFoundException e){System.out.println("加载驱动的时候出了错误");System.exit(0);}
conn=DriverManager.getConnection(myurl,myuser,mypass);
//myst=conn.createStatement();
myst= conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
//mysql="select id,simname,name from lineway where parentid='AAAA'";
mysql="Select "+ mylable+","+myindex +" from "+mytable +" where "+myparent+"='AAAA'";
myresult=myst.executeQuery(mysql);
myresult.next();
String lable_this=myresult.getString(mylable);
MytreeNode root=new MytreeNode(lable_this);
root.setMylable(lable_this);
root.setMydata(myresult.getString(myindex));
mytree=new JTree(root);
mymodel=(DefaultTreeModel)mytree.getModel();
insertNodes(root);
return mytree;
}
private void insertNodes(MytreeNode node) throws SQLException
{
String node_data;
int rcount;
node_data=node.getMydata();
mysql="select "+mylable+","+myindex +" from "+mytable+" where "+myparent+"='"+node_data+"' order by "+myindex+" asc";
myresult=myst.executeQuery(mysql);
System.out.println("获取查询结果数之前!");
//向当前的节点插入查询结果
System.out.println(mysql);
rcount=getResultCount(myresult);
System.out.println("获取查询结果数之后!");
if (rcount > 1)//如果当前有子节点的话就把它插入
{
MytreeNode[] children = new MytreeNode[rcount];
for(int j = 0;j<rcount;j++)
{
MytreeNode node_new=new MytreeNode(myresult.getString(myindex)+"-"+myresult.getString(mylable));
node_new.setMylable(myresult.getString(mylable));
node_new.setMydata(myresult.getString(myindex));
children[j]=node_new;//保存当前插入的子节点
mymodel.insertNodeInto(node_new,node,node.getChildCount());
myresult.next();
}
System.out.println("已经插入当前的查询结果!!");
//如果当前点有子节点则调用insertNodes()直到把所有的对象都插入进去
for(int j = 0;j<rcount;j++)
{
insertNodes(children[j]);
}
System.out.println("已经插入所有的查询结果!!");
}
}
private int getResultCount(ResultSet result) throws SQLException//获取查询结果树并把记录移动到第一条记录
{
int i = 0;
while(result.next())
{
i++;
}
System.out.println("已经获取查询结果数:"+i);
try{
result.first();
}catch(SQLException e){System.out.println("指针移不到第一条记录!");}
return i;
}
}
//====================================================================
//DefaultMutableTreeNode:树的节点
// r=new DefaultMutableTreeNode("Lable")
// r.add(new DefaultMutableTreeNode("Lable2")
//DefaultTreeModel model;
// model=(DefaultTreeModel)tree.getModel();
// model.insertNodeInto(child,chosen,0)//插入并自动更新界面
//Jtree tree;
// tree=new Jtree(toot);
// chosen=(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();//返回当前选取的节点对象
//返回当前展开的节点和将要展开的节点 如何展开一个节点。
//
//
//
XML文档和JTree之间如何转换?
XML因为良好的结构,被广泛地应用于文档格式的定义。我们知道,应用软件一般需要用配置文件来决定运行时的一些参数。以前的应用程序的配置文件一般是一个.ini文件。虽然现在,ini文件仍然在使用,但是由于XML的出现,越来越多的商用软件正在把XML当作配置文件的格式,如BEA的Weblogic,以及IBM的Websphere等。所以,当我们设计一个软件的配置文件时,将会越来越多地考虑使用XML作为该配置文件的格式。
而因为配置文件有时候必须让用户修改,所以提供一个可视化的编辑配置文件的格式,是一个软件具有良好的用户可交互性的体现。我们必须给XML文档找到一个可视化的方法。Java语言中的Swing组件里面的JTree,用于XML文档的可视化是非常适合的。这两者之间存在着很方便的转换方法。这就意味着我们能将用户在JTree上面的操作,在存盘后方便地表现为在XML文件中的修改,也能将XML文件方便地表现为一棵JTree展现给用户。
XML文档的可视化
一个XML文档其实是一个树形的结构。比如下面这个XML文档:
〈?xml version=“1.0”encoding=“GB2312”?〉
〈skin〉
〈skin1〉
〈name〉古典〈/name〉
〈dir〉d:softwareAppskin〈/dir〉
〈head〉head1.bmp〈/head〉
〈center〉center1.bmp〈/center〉
〈foot〉foot1.bmp〈/foot〉
〈/skin1〉
〈skin2〉
〈name〉现代〈/name〉
〈dir〉d:softwareAppskin〈/dir〉
〈head〉head2.bmp〈/head〉
〈center〉center2.bmp〈/center〉
〈foot〉foot2.bmp〈/foot〉
〈/skin2〉
〈/skin〉
可以看得出来,该XML文档是一个多界面程序的界面图片配置程序,如果将该XML文档可视化,那么使用JTree的话应该得到的是如下图所示的结果。
图 可视化结果
所有的XML文档,都能够生成这样一个Jtree。使用XML的Parser和Java里的JTree类,可以构造出一个通用的可视化XML文档从而构成一棵JTree。XML Parser对XML文档解析的结果是生成一颗DOM(Document Object Model)树,DOM树的结构和JTree的结构其实是一样的,这使JTree和XML Parser的配合非常自然。下面就介绍一下做法。
一个读写XML文件的类
首先必须获得XML Parser的包,可以从下面的地址获得:http://xml.apache.org/xerces2-j/index.html。
然后设计一个XMLTree的类,继承自JTree类的定义和成员变量,函数定义如下:
public class XMLTree extends JTree{
private DefaultMutableTreeNode treeNode; //JTree的根节点
private DocumentBuilderFactory dbf;
// 这三个成员变量是xml parser需要的
private DocumentBuilder db;
private Document doc;
XMLTree(String fileName);
//构造函数,做初始化工作
public DefaultMutableTreeNode LoadFile(Node root);
//从某个XML文件生成该树
public void SaveToFile(DefaultMutableTreeNode root,FileWriter fw);
//将该树存盘成XML文件
private Node parseXml( String text )
}
其中构造函数所做的初始化工作如下:
XMLTree(String fileName){
dbf = DocumentBuilderFactory.newInstance();
//生成dbf的实例
db = dbf.newDocumentBuilder();
//生成db的实例
treeNode = LoadFile( getXMLRoot( text ) );
//解析该xml文件,返回JTree的根节点
setModel( new DefaultTreeModel( treeNode ) );
//根据该根节点生成JTree
}
其中,parseXml是一个返回XML文件根元素的程序,如下:
private Node getXMLRoot( String text ){
ByteArrayInputStream byteStream;
byteStream = new ByteArrayInputStream( text.getBytes() );
//将XML文件读到Stream里去
try{
doc = db.parse( byteStream );
//解析该xml文件。
} catch ( Exception e )
{ e.printStackTrace();}
return ( Node )doc.getDocumentElement();
//返回该XML文件的DOM树的根元素
}
核心部分的LoadFile是一个递归过程,如下:
private DefaultMutableTreeNode createTreeNode( Node root ){
DefaultMutableTreeNode treeNode = null;
//定义要返回的根节点
String name = root.getNodeName();
//获得该节点的NodeName
String value = root.getNodeValue();
//获得该节点的NodeValue
treeNode = new DefaultMutableTreeNode( root.
getNodeType() == Node.TEXT_NODE ? value : name );
//如果为值节点,那么取得该节点的值,否则取得该节点的Tag的名字
if ( root.hasChildNodes() )
//如果该节点有孩子节点,那么递归处理该节点的孩子节点
{ NodeList children = root.getChildNodes();
//取得该节点的子节点列表
if( children != null ){
//判断子节点是否为空
int numChildren = children.getLength();
//取得字节数目
for (int i=0; i 〈 numChildren; i++){
Node node = children.item(i);
//循环处理每个子节点
if( node != null )
{ if( node.getNodeType() == Node.ELEMENT_NODE )
{ treeNode.add( createTreeNode(node) );
//如果该子节点还有孩子节点使用递归的方法处理该子节点
} else {
String data = node.getNodeValue();
if( data != null )
{
data = data.trim();
if ( !data.equals(“ ”) && !data.equals(“ ”) &&
data.length() 〉 0 )
{ treeNode.add(new
DefaultMutableTreeNode(node.getNodeValue()));
//如果该节点没有孩子节点,那么直接加到节点下
}
}
}
}
}
}
}
return treeNode; //返回节点 }
使用Java的Swing包里的方法能够很容易地在JTree上做改动,可以使用弹出对话框的方法,也可以直接在JTree上改动。总之,JTree改动后,需要重新写回文件中去将一棵JTree写成XML文件是一个递归的过程,方法如下:
public void SaveToFile(DefaultMutableTreeNode, FileWriter fw)
{try {
if (root.isLeaf()) fw.write(root.toString()+“ ”);
//如果是叶子节点则直接将该节点输出到文件中
else { //不是叶子节点的话递归输出该节点
fw.write(“〈”+root.toString()+“〉 ”);
for (int i=0; i 〈 root.getChildCount(); i++)
{ DefaultMutableTreeNode childNode =(DefaultMutableTreeNode)
root.getChildAt(i);
saveFile(childNode, fw);
//递归输出该节点的所有子节点 }
fw.write(“〈/”+root.toString()+“〉 ”);
}
} catch (Exception e)
{ e.printStackTrace();
} }
必须注意的是,如果XML文件中包含中文,那么需要在调用上面的函数之前,先在文件中输入该XML文件的编码方式,方法如下:
fw.write(“〈?xml version=“1.0” encoding=“GB2312”?〉 ”);
在调用该函数结束后,还应该关闭该文件,方法是:
fw.close()
| ||||
|