JTree操作API

本文详细介绍了Java Swing中的JTree组件的操作,包括创建树组件、获取与更新树节点、节点遍历与操作,以及事件处理和渲染。此外,还提及了Hibernate中HQL语句返回类型安全Java对象的注意事项。

JTree操作API归纳

1.1 创建树组件
1.1.1 最简方式

    JTree tree  =   new  JTree();

    在显示时,树组件会带上JTree默认的节点。

1.1.2 指定树的节点后创建树:   

    DefaultMutableTreeNode root  =   new  DefaultMutableTreeNode( " 根节点 " );
    root.add(
new  DefaultMutableTreeNode( " 子节点 " ));    
    JTree tree 
=   new  JTree(root);


1.1.3 将树加入到面板中
    以下是将树加上滚动窗格后加入一个面板的示例程序。    

   JPanel panel = new  JPanel();
   panel.setLayout(
new  GridLayout( 1 , 1 ));
   panel.add(
new  JScrollPane(tree));

   
1.2 树节点相关
1.2.1 取得树的根节点

    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 树的事件处理
1.3.1 左键点击事件处理
   

   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()); //  返回节点所在的行,-1表示鼠标定位不在显示的单元边界内
        TreePath selPath  =  tree.getPathForLocation(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 树的渲染
1.4.1 树节点渲染器示例
 

  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());

 

posted @ 2010-01-14 15:13 heyang| 编辑 收藏

Hibernate中HQL语句直接返回类型安全的Java对象的注意点

当不需要全体字段或是不必要的字段属性映射匹配影响效率时,我们可以使用在HQL语句中直接返回一个Java对象,如下:
select new com.heyang.domain.Folder(id,pid,name) from Category c

需要注意的是:
1.Folder类应该写全路径名,如上面的com.heyang.domain.Folder,否则Hibernate会说Unable to locate class ‘Folder’。

2.Folder类应该具有一个和参数相匹配的构造函数,如果上面的id,pid,name三个字段的类型分别是long,long,vchar,那么Folder类的构造函数应该是Folder(Long op1,Long op2,String op3);的形式。

就是这样,很简单,简单到Hibernate帮助手册都对之语焉不详,写出来注意一下就好了。

posted @ 2010-01-09 09:01 heyang| 编辑 收藏

一个目录缓存设计的进化过程.

任务:数据库中有六千余条目录(id,pid,name)数据组成一棵目录树,需要通过WebService服务提供给客户端显示出来(Swing中的JTree)。

实现功能的第一步:在客户端的树显示时通过网络得到顶层目录,再根据用户的点击逐级展开下级目录。此方案优点:实现简单;缺点:点击多次容易使人厌烦,速度不行。

客户端实现改善的第二步:启动一个线程从服务器加载数据逐渐生成一个节点树,再交给界面上的JTree命其更新。此举对操作友好型有改进,速度上也有所提高。

客户端实现改善的第三步:先起线程从服务器端一次性下载完全部数据,而后置入内存,再以此为基础构建树。此举对速度也有明显提高。

客户端实现改善的第四步:将已经加载的节点从内存中删除,使查找时间逐渐减小。此举对速度有一定提高。

服务器端实现改善的第四步:不使用Hibernate的对象映射而单独遴选字段组建成一个包装类,此举对速度有一定提高。

服务器端实现改善的第五步:直接采用优化的存储过程将表中必要行集的数据在数据库段形成大文本,一次性传出,WS服务器端只负责传输,此举对速度有明显提高。

通过以上措施,完成包括六千个节点的树显示速度数量级的提高,综合评价一下,以上逐步中,第三步:在客户端另起线程从内存加载数据形成一棵完整的节点树再通知界面更新 和 第五步:通过存储过程直接取得行集合并结果对提高速度帮助最大。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值