java如何实现无限级树,用java小程序applet实现无限级树结构

该博客介绍了如何使用Java小程序Applet动态构建无限级树结构,该树结构从XML文件中读取数据并支持一次加载和动态加载。树的深度由XML文件决定,具有复用性和良好的用户交互性。主要通过三个类实现:TreeNode描述树的数据结构,IconRender设置节点图标,AppletTree作为主要类继承自Applet并监听用户操作。当用户点击节点时,通过URL将操作传递给服务器进行相应处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该程序可以根据从指定的xml文件中读取的有关信息动态的建立一棵树。

1.该树的特点:

1)无限级树结构

http://www.gaodaima.com/41394.html用java小程序applet实现无限级树结构

理论上树的深度可以无限,树的深度由xml文件所给的信息确定;

数据加载采用一次加载和动态加载相结合的方法;

每次打开相关页时重新加载树结构,真正的做到了建立树的动态性。

2)复用性

由于这棵树是通过读取xml文件建立的,树的程序代码固定,所以具有很强的复用性。只需要给出xml文件,程序就可以建立对应的树。

3)与用户的交互

由于该程序是用java小程序实现的,所以可以利用java语言中监听事件的类,以响应用户操作。与用户具有更好的交互性。

2.程序结构

这棵树主要有三个类实现:

1) 类TreeNode:该类起辅助作用,用来描述树的数据结构,并提供一些setter,getter函数用来设置树结构的属性。

2) 类IconRender:该类也是一个辅助类,用来设置树节点的图标。并且可以根据树节点的选中状态改变图标。

3) 类AppletTree:该类是建立这棵树的主要类,它继承自Applet并且实现了TreeSelectionListener接口,以用来监听用户操作。树结构由java类JTree显示,我们只需要合理的设定JTree的属性就可以构造出这棵树。而它的属性是通过jdom中的Element读取xml文件提供的。上面已经提到监听用户操作是通过实现TreeSelectionListener接口完成的,但是只监听不响应毫无用处。怎样才能将监听到的用户操作传给相应的类以响应用户的操作呢?这里用的方法是通过URL将参数传递给jsp文件,再由jsp文件传给相应的操作类实现的。

这三个类的代码如下:

1.TreeNode类

public class TreeNode{

private String id;

private String name;

private String link;

public TreeNode(String id,String name,String link){

this.id=id;

this.name=name;

this.link=link;

}

public String getId(){

return id;

}

public void setId(String Id){

this.id=Id;

}

public void setName(String Name){

this.name=Name;

}

public String getName(){

return name;

}

public String toString(){

return name;

}

public String getLink(){

return link;

}

public void setLink(String link){

this.link=link;

}

}

2. IconRender类

import javax.swing.*;

import java.awt.*;

import javax.swing.tree.*;

import javax.swing.tree.DefaultTreeCellRenderer;

IconRender

class extends DefaultTreeCellRenderer {

//创建用于显示的图标

public static final ImageIcon leafSelectedIcon = new ImageIcon("OpenedFolder.ico");

public static final ImageIcon leafUnSelectedIcon = new ImageIcon("closedFolder.ico");

public static final ImageIcon folderOpen = new ImageIcon("OpenedFolder.ico");

public static final ImageIcon folderClose = new ImageIcon("closedFolder.ico");

//设定图标随选中状态的变化

public Component getTreeCellRendererComponent(JTree

tree,Object value,boolean selected,boolean expanded,

boolean leaf, int row,boolean hasFocus)

{

super.getTreeCellRendererComponent(tree,value, selected, expanded, leaf, row, hasFocus);

if (leaf && selected) {

setIcon(IconRender.leafSelectedIcon);

}

else if (leaf) {

setIcon(IconRender.leafUnSelectedIcon);

}

return this;

}

public IconRender() {

super();

if((leafSelectedIcon != null)&&(leafUnSelectedIcon != null))

System.out.println("IconRender:trace");

setLeafIcon(leafUnSelectedIcon);

setOpenIcon(folderOpen);

setClosedIcon(folderClose);

}

}

3.AppletTree类

import javax.swing.event.*;

import java.awt.*;

import java.applet.*;

import javax.swing.*;

import javax.swing.tree.*;

import java.awt.event.*;

import org.jdom.*;

//import org.w3c.dom.NodeList;

import org.jdom.input.*;

import java.io.*;

import java.util.*;

import java.net.*;

import java.awt.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.plaf.*;

import javax.swing.plaf.basic.*;

import javax.swing.plaf.metal.*;

import java.io.*;

//import netscape.JavaScript.*;

class MyWindowListener extends WindowAdapter

{

public void windowClosing(WindowEvent e)

{

System.exit(1);

}

}

public class AppletTree extends Applet implements TreeSelectionListener

{

private JTree tree;

private TreePath path;

private JScrollPane treeView;

private DefaultMutableTreeNode top;

private DefaultMutableTreeNode clicknode;

private String link;

public AppletTree(){

}

MouseListener ml = new MouseAdapter() {

public void mousePressed(MouseEvent e) {

int selRow = tree.getRowForLocation(e.getX(), e.getY());

TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());

if(selRow != -1) {

if(e.getClickCount() == 1) {

System.out.print("点击一次鼠标");

//得到最后一个节点

DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)selPath.getLastPathComponent();

boolean isLeaf = treeNode.isLeaf();

TreeNode objTreeNode = (TreeNode)treeNode.getUserObject();

System.out.println(isLeaf);

System.out.println(objTreeNode .getName()) ;

System.out.println(objTreeNode .getId()) ;

if(isLeaf)

{//如果为叶子节点就传出去进行查询操作

try

{

getAppletContext().showDocument(new URL("http://127.0.0.1:8080/tree/showDevice.htm"),"f2" );

}

catch(Exception ex)

{

System.out.print(ex);

}

}

}

else if(e.getClickCount() == 2) {

System.out.print("点击两次鼠标");

//getAppletContext().showDocument(new URL("http://www.youkuaiyun.com/"));

//myDoubleClick(selRow, selPath);

}

}

}

};

public void start()

{

super.start();

}

public void init(){

try{

super.init();

this.setLayout(new GridLayout(1,1));

tree=createTree(new FileInputStream("e:/example/TreeXML.xml"));

tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

tree.putClientProperty("JTree.lineStyle","Angled");

tree.setShowsRootHandles(true);

tree.setEditable(true);

tree.addTreeSelectionListener( this );

IconRender render=new IconRender();

tree.setCellRenderer(render);

treeView = new JScrollPane(tree);

//topPanel.add(tree);

this.add(treeView);

tree.addMouseListener(ml);

}catch(Exception e){

e.printStackTrace();

}

}

public JTree createTree(InputStream is){

SAXBuilder builder = new SAXBuilder();

try {

Document doc = builder.build(is);

Element root=doc.getRootElement();

TreeNode rootNode=new

TreeNode(root.getAttributeValue("id"),root.getAttributeValue("name"),root.getAttributeValue("HaveChildren"));

top=new DefaultMutableTreeNode(rootNode);

addNode(root,top);

} catch (Exception ex) {

ex.printStackTrace();

}

//可以在这里改变jtree中连线的颜色

UIManager.put( "Tree.hash", new ColorUIResource(Color.red) );

return new JTree(top);

}

/**

*

* @param e 待加入树中的jdom元素

* @param fatherNode 树节点父亲节点

*/

private void addNode(Element e,DefaultMutableTreeNode fatherNode){

try{

Iterator it=e.getChildren().iterator();

if(!it.hasNext())

return;

while(it.hasNext()){

Element sub=(Element)it.next();

String id=new String(sub.getAttributeValue("id").getBytes(),"GB2312");

String name=new String(sub.getAttributeValue("name").getBytes(),"GB2312");

String link=new String(sub.getAttributeValue("HaveChildren").getBytes(),"GB2312");

System.out.println(id);

System.out.println(name);

System.out.println(link);

TreeNode tempNode=new TreeNode(id,name,link);

DefaultMutableTreeNode node=new DefaultMutableTreeNode(tempNode);

fatherNode.add(node);

if(link.equals("true")){

System.out.println("true~! equal test");

addNode(sub,node);

}

}

}

catch(Exception exp)

{

System.out.println("encoding fail");

}

}

/**

* 根据id,查找树节点,//广度优先

* @param id 节点id

* @param rootNode 树根节点

* @return DefaultMutableTreeNode

*/

private DefaultMutableTreeNode getTreeNode(String id,DefaultMutableTreeNode rootNode){

DefaultMutableTreeNode returnNode=null;

if(rootNode!=null){

Enumeration enum=rootNode.breadthFirstEnumeration();

while(enum.hasMoreElements()){

DefaultMutableTreeNode temp=(DefaultMutableTreeNode)enum.nextElement();

TreeNode node=(TreeNode)temp.getUserObject();

if(node.getId().equals(id)){

returnNode=temp;

break;

}

}

}

return returnNode;

}

public void valueChanged( TreeSelectionEvent event ){

if( event.getSource() == tree ){

path = event.getPath();

clicknode=(DefaultMutableTreeNode)path.getLastPathComponent();

Object uo=clicknode.getUserObject();

if(uo instanceof TreeNode){

TreeNode nd=(TreeNode)clicknode.getUserObject();

link=nd.getLink();

}

}

}

public static void main(String[] args ){

JFrame frame1=new JFrame("test");

AppletTree tree=new AppletTree();

tree.init();

frame1.getContentPane().add(tree);

frame1.setSize(600,600);

frame1.show();

frame1.addWindowListener(new MyWindowListener());

}

}

欢迎大家阅读《用java小程序applet实现无限级树结构》,跪求各位点评,若觉得好的话请收藏本文,by 搞代码

e7ce419cf2d6ad34d01da2ceb8829eed.png

微信 赏一包辣条吧~

023a57327877fb4402bcc76911ec18ea.png

支付宝 赏一听可乐吧~

无限级Java递归) 2007-02-08 10:26 这几天,用java写了一个无限极的,递归写的,可能代码不够简洁,性能不够好,不过也算是练习,这几天再不断改进。前面几个小图标的判断,搞死我了。 package com.nickol.servlet; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.nickol.utility.DB; public class category extends HttpServlet { /** * The doGet method of the servlet. * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println(""); out.println(""); out.println(" Category" + "" + "body{font-size:12px;}" + "" + "" + ""); out.println(" "); out.println(showCategory(0,0,new ArrayList(),"0")); out.println(" "); out.println(""); out.flush(); out.close(); } public String showCategory(int i,int n,ArrayList frontIcon,String countCurrent){ int countChild = 0; n++; String webContent = new String(); ArrayList temp = new ArrayList(); try{ Connection conn = DB.GetConn(); PreparedStatement ps = DB.GetPs("select * from category where pid = ?", conn); ps.setInt(1, i); ResultSet rs = DB.GetRs(ps); if(n==1){ if(rs.next()){ webContent += "";//插入结尾的减号 temp.add(new Integer(0)); } webContent += " ";//插入站点图标 webContent += rs.getString("cname"); webContent += "\n"; webContent += showCategory(Integer.parseInt(rs.getString("cid")),n,temp,"0"); } if(n==2){ webContent += "\n"; }else{ webContent += "\n"; } while(rs.next()){ for(int k=0;k<frontIcon.size();k++){ int iconStatic = ((Integer)frontIcon.get(k)).intValue(); if(iconStatic == 0){ webContent += "";//插入空白 }else if(iconStatic == 1){ webContent += "";//插入竖线 } } if(rs.isLast()){ if(checkChild(Integer.parseInt(rs.getString("cid")))){ webContent += "";//插入结尾的减号 temp = (ArrayList)frontIcon.clone(); temp.add(new Integer(0)); }else{ webContent += "";//插入结尾的直角 } }else{ if(checkChild(Integer.parseInt(rs.getString("cid")))){ webContent += "";//插入未结尾的减号 temp = (ArrayList)frontIcon.clone(); temp.add(new Integer(1)); }else{ webContent += "";//插入三叉线 } } if(checkChild(Integer.parseInt(rs.getString("cid")))){ webContent += " ";//插入文件夹图标 }else{ webContent += " ";//插入文件图标 } webContent += rs.getString("cname"); webContent += "\n"; webContent += showCategory(Integer.parseInt(rs.getString("cid")),n,temp,countCurrent+countChild); countChild++; } webContent += "\n"; DB.CloseRs(rs); DB.ClosePs(ps); DB.CloseConn(conn); }catch(Exception e){ e.printStackTrace(); } return webContent; } public boolean checkChild(int i){ boolean child = false; try{ Connection conn = DB.GetConn(); PreparedStatement ps = DB.GetPs("select * from category where pid = ?", conn); ps.setInt(1, i); ResultSet rs = DB.GetRs(ps); if(rs.next()){ child = true; } DB.CloseRs(rs); DB.ClosePs(ps); DB.CloseConn(conn); }catch(Exception e){ e.printStackTrace(); } return child; } } --------------------------------------------------------------------- tree.js文件 function changeState(countCurrent,countChild){ var object = document.getElementById("level" + countCurrent + countChild); if(object.style.display=='none'){ object.style.display='block'; }else{ object.style.display='none'; } var cursor = document.getElementById("cursor" + countCurrent + countChild); if(cursor.src.indexOf("images/tree_minus.gif")>=0) {cursor.src="images/tree_plus.gif";} else if(cursor.src.indexOf("images/tree_minusbottom.gif")>=0) {cursor.src="images/tree_plusbottom.gif";} else if(cursor.src.indexOf("images/tree_plus.gif")>=0) {cursor.src="images/tree_minus.gif";} else {cursor.src="images/tree_minusbottom.gif";} var folder = document.getElementById("folder" + countCurrent + countChild); if(folder.src.indexOf("images/icon_folder_channel_normal.gif")>=0){ folder.src = "images/icon_folder_channel_open.gif"; }else{ folder.src = "images/icon_folder_channel_normal.gif"; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值