JTree 不同叶子节点图标
引自:http://blog.csdn.net/jimmy292/archive/2010/03/03/5341192.aspx 1.1 创建树组件
??? JTree?tree?
=
?
new
?JTree();
??? 在显示时,树组件会带上JTree默认的节点。 1.1.2 指定树的节点后创建树: ???
??? DefaultMutableTreeNode?root?
=
?
new
?DefaultMutableTreeNode(
"
根节点
"
);
???? root.add( new ?DefaultMutableTreeNode( " 子节点 " ));???? ?????JTree?tree? = ? new ?JTree(root);
?? JPanel?panel
=
new
?JPanel();
??? panel.setLayout( new ?GridLayout( 1 , 1 )); ??? panel.add( new ?JScrollPane(tree)); ? ???
????DefaultTreeModel?model?
=
?(DefaultTreeModel)?tree.getModel();
????DefaultMutableTreeNode?root? = (DefaultMutableTreeNode)model.getRoot(); 1.2.2 更新树的根节点
????DefaultMutableTreeNode?newRoot
=
????DefaultTreeModel?model? = ?(DefaultTreeModel)?tree.getModel(); ????model.setRoot(newRoot); ????model.reload();?? ????tree.updateUI(); 1.2.3 从一个节点开始递归遍历其下的所有节点
private
?String?getNodeText(DefaultMutableTreeNode?node){
?? Category?category = (Category)node.getUserObject(); ?? StringBuilder?sb = new ?StringBuilder(category.getText()); ?? ?? if ?(node.getChildCount()? >= ? 0 )?{ ???????????? for ?(Enumeration <?> ?e = node.children();?e.hasMoreElements();?)?{ ?????????????DefaultMutableTreeNode?childNode? = ?(DefaultMutableTreeNode)e.nextElement(); ????????????????sb.append(getNodeText(childNode)); ????????????} ????????} ?? ?? return ?sb.toString(); } 1.2.4 在某节点下创建一个节点
????DefaultMutableTreeNode?childNode?
=
?
new
?DefaultMutableTreeNode();
????childNode.setUserObject( ????parentNode.add(childNode); 1.2.5 节点改名 ??
??? Category?selectedCategory
=
(Category)clickedNode.getUserObject();
????selectedCategory.setName( " ????clickedNode.setUserObject(selectedCategory); 1.2.6 删除节点 ???
??? DefaultTreeModel?model?
=
?(DefaultTreeModel)tree.getModel();
????model.removeNodeFromParent(clickedNode); ??? 注意被删除的节点必须有父节点,若要删除根节点直接用null去替代原有根节点即可, 1.2.7 遍历用户选择的树节点 ???
??? TreePath[]?paths?
=
?tree.getSelectionPaths();
??? ???? for (TreePath?selPath:paths){ ????????Object[]?nodes? = ?selPath.getPath(); ?? ????????DefaultMutableTreeNode?node? = ?(DefaultMutableTreeNode)?nodes[nodes.length? - ? 1 ];?? ???????? // ?对node进行处理 ????} 1.3 树的事件处理
?? tree.addMouseListener(
new
?MouseAdapter()?{
?????? public ? void ?mousePressed(MouseEvent?e)?{ ???????? int ?selRow? = ?tree.getRowForLocation(e.getX(),?e.getY()); // ?返回节点所在的行,-1表示鼠标定位不在显示的单元边界内 ????????TreePath?selPath? = ?tree.getPathForLocation(e.getX(),?e.getY()); // ?返回指定节点的树路径 ??? ???????? boolean ?condition? = ? true ; ????????condition? = ?condition? && ?(selRow? != ? - 1 ); // ?如果选中 ???????? // condition?=?condition?&&?(e.getButton()?==?1); // ?左键?e.getButton()?==?1??右键??e.getButton()?==?3 ????????condition? = ?condition? && ?(e.getClickCount()? == ? 1 ); // ?单击 ??????? ??? ???????? // ?如果是左键点击 ???????? if ?(condition? == ? true ? && ?(e.getButton()? == ? 1 ))?{ ??????????Object[]?nodes? = ?selPath.getPath(); ????????? ??????????DefaultMutableTreeNode?node? = ?(DefaultMutableTreeNode)?nodes[nodes.length? - ? 1 ]; ??????????Category?selectedCategory = (Category)node.getUserObject(); ??? ????????} ??????} ????}); 1.3.2 在树节点上点击右键弹出右键菜单 ?
?? tree.addMouseListener(
new
?MouseAdapter()?{
?????? public ? void ?mousePressed(MouseEvent?e)?{ ???????? int ?selRow? = ?tree.getRowForLocation(e.getX(),?e.getY()); // ?返回指定节点的树路径 ???????? boolean ?condition? = ? true ; ????????condition? = ?condition? && ?(selRow? != ? - 1 ); // ?如果选中 ????????condition? = ?condition? && ?(e.getClickCount()? == ? 1 ); // ?单击 ??????? ???????? // ?如果是右键点击 ???????? if (condition? == ? true ? && ?(e.getButton()? == ? 3 )){ ????????? ??????????Object[]?nodes? = ?selPath.getPath(); ??????????DefaultMutableTreeNode?rightClickedNode? = ?(DefaultMutableTreeNode)?nodes[nodes.length? - ? 1 ]; ?????????? ??????????popupMenu.show(e.getComponent(),?e.getX(),?e.getY()); ????????} ??????} ????}); 1.4 树的渲染
? public
?
class
?CategoryNodeRenderer?
extends
?DefaultTreeCellRenderer{
???? private ? static ? final ? long ?serialVersionUID? = ? 8532405600839140757L ; ??? ???? private ? static ? final ?ImageIcon?categoryLeafIcon? = ? new ?ImageIcon(CategoryNodeRenderer. class .getResource( " /categoryLeaf.gif " )); ???? private ? static ? final ?ImageIcon?openFolderIcon? = ? new ?ImageIcon(CategoryNodeRenderer. class .getResource( " /openFolder.gif " )); ???? private ? static ? final ?ImageIcon?closedFolderIcon? = ? new ?ImageIcon(CategoryNodeRenderer. class .getResource( " /closedFolder.gif " )); ??? ???? public ?Component?getTreeCellRendererComponent(JTree?tree, ??????????????????????????????????????????????Object?value, ?????????????????????????????????????????????? boolean ?sel, ?????????????????????????????????????????????? boolean ?expanded, ?????????????????????????????????????????????? boolean ?leaf, ?????????????????????????????????????????????? int ?row, ?????????????????????????????????????????????? boolean ?hasFocus){ ????? ?????? super .getTreeCellRendererComponent(tree,?? ??????????????????value, ??????????????????sel,?? ??????????????????expanded,?? ??????????????????leaf,?? ??????????????????row,?? ??????????????????hasFocus);?? ????? ?????? if (leaf){ ????????setIcon(categoryLeafIcon); ??????} ?????? else ? if (expanded){ ????????setIcon(openFolderIcon); ??????} ?????? else { ????????setIcon(closedFolderIcon); ??????} ????????? ?????? return ? this ;??? ????} ??} 1.4.2 用树节点渲染器渲染一棵树 ?
? DefaultMutableTreeNode?root?
=
?
null
;
??JTree?tree? = ? new ?JTree(root); ??tree.setCellRenderer( new ?CategoryNodeRenderer()); ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 一个目录缓存设计的进化过程: 任务:数据库中有六千余条目录(id,pid,name)数据组成一棵目录树,需要通过WebService服务提供给客户端显示出来(Swing中的JTree)。实现功能的第一步:在客户端的树显示时通过网络得到顶层目录,再根据用户的点击逐级展开下级目录。此方案优点:实现简单;缺点:点击多次容易使人厌烦,速度不行。客户端实现改善的第二步:启动一个线程从服务器加载数据逐渐生成一个节点树,再交给界面上的JTree命其更新。此举对操作友好型有改进,速度上也有所提高。客户端实现改善的第三步:先起线程从服务器端一次性下载完全部数据,而后置入内存,再以此为基础构建树。此举对速度也有明显提高。客户端实现改善的第四步:将已经加载的节点从内存中删除,使查找时间逐渐减小。此举对速度有一定提高。服务器端实现改善的第四步:不使用Hibernate的对象映射而单独遴选字段组建成一个包装类,此举对速度有一定提高。服务器端实现改善的第五步:直接采用优化的存储过程将表中必要行集的数据在数据库段形成大文本,一次性传出,WS服务器端只负责传输,此举对速度有明显提高。通过以上措施,完成包括六千个节点的树显示速度数量级的提高,综合评价一下,以上逐步中,第三步:在客户端另起线程从内存加载数据形成一棵完整的节点树再通知界面更新 和 第五步:通过存储过程直接取得行集合并结果对提高速度帮助最大。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |