同步选中,展开和闭合具有不同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()方法找到要同步的节点,将其选中,根据要求展开或者闭合。
/**2
* Sychronize <code>tree2</code> by <code>path</code>.3
* @param path4
* @param tree25
* @param rootNode26
*/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()方法就可以了。

浙公网安备 33010602011771号