永无止境的程序

..::[......]::..

导航

同步选中,展开和闭合具有不同TreeModel的JTree中的节点

最近用Swing做了一个比较工具,比较两个数据库的Schema的异同,比较完成以后将的结果显示在界面上左右两个JTree里。比较结果不包含Schema种所有相同的内容,只包含不同的。显示的结果可能比较多,我就考虑,最好有这样一个功能:选中左边任何一个节点的时候,如果右边有相应的节点的话就找到选中它高亮显示,反之亦然。那么考虑监听JTree1的TreeSelectionEvent事件,该事件提供一个方法getNewLeadSelectionPath(),该方法返回一个值,指明了被选中节点的TreePath,我想可以用这个TreePath来选中另外一个JTree2的相应节点。
但是在实际操作的过程中发现,JTree1的TreePath无法用于JTree2的JTree.expandPath()方法,除非两个JTree的TreeModel是同一个。但是如果JTree的DataModel是同一个的话两个JTree中的所有的数据也必然是相同的,这和我的程序要求是不相符合的。
那么我只能手动来同步这两个DataModel不同的JTree了。先写一个JTree的工具类,包含了一个方法GetSubNodeByNames(),该方法通过一个给定的节点名数组在另外一个JTree中找到相应的那个节点,如果没有返回其父节点,直到根节点。这样的话我只要从事件TreeSelectionEvent提供的TreePath中提取到所有节点的名字就可以了。

    /**
     * Get last node of the nodeNames. If not exist, return parent node until root node.
     * @param nodeNames
     * @param parentNode
     * @param startFrom
     * @return
     
*/

    
public static DefaultMutableTreeNode GetSubNodeByNames(Object[] nodeNames, DefaultMutableTreeNode parentNode, int startFrom) {
        
if (startFrom >= nodeNames.length)
            
return parentNode;
        DefaultMutableTreeNode curNode 
= GetSubNodeByName(nodeNames[startFrom++].toString(), parentNode);
        
if (curNode == null{
            
return parentNode;
        }
 else {
            
return GetSubNodeByNames(nodeNames, curNode, startFrom);
        }

    }


    
/**
     * Get sub node by given name.
     * @param name
     * @param parentNode
     * @return
     
*/

    
public static DefaultMutableTreeNode GetSubNodeByName(String name, DefaultMutableTreeNode parentNode) {
        
if (parentNode.isLeaf())
            
return null;
        
for (DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) parentNode.getFirstChild(); curNode != null; curNode = curNode
                .getNextSibling()) 
{
            
if ((curNode.getUserObject()).toString().startsWith(name)) {
                
return curNode;
            }

        }

        
return null;
    }

然后写一个SyncTreeNode方法,它取得TreePath路径上所有的节点的名字,用前面定义的GetSubNodeByNames()方法找到要同步的节点,将其选中,根据要求展开或者闭合。

 1    /**
 2     * Sychronize <code>tree2</code> by <code>path</code>.
 3     * @param path
 4     * @param tree2
 5     * @param rootNode2
 6     */

 7    public static void SyncTreeNode(TreePath path, JTree tree2, DefaultMutableTreeNode rootNode2, boolean isExpand) {
 8        if(path == null)return;
 9        Object[] nodeNames = path.getPath();
10        DefaultMutableTreeNode node = GetSubNodeByNames(nodeNames, rootNode2, 1);
11        System.out.println("Wanted node : " + node + "  and leval is " + node.getLevel());
12        if (node.getParent() != null{
13            TreePath path2 = new TreePath(node.getPath());
14            if(isExpand == true){
15            tree2.expandPath(path2);
16            tree2.setSelectionPath(path2);
17            }
else{
18                tree2.collapsePath(path2);
19            }

20            tree2.scrollPathToVisible(path2);
21        }

22    }

23


完成这些以后就差不多了,最后就是响应界面上的事件了,监听TreeExpansionEvent,TreeExpansionEvent和TreeSelectionEvent事件,调用SyncTreeNode()方法就可以了。

posted on 2005-05-19 17:29  AlleNny  阅读(2498)  评论(3)    收藏  举报