Java tips(2): 讓不包含子結(jié)點(diǎn)的TreeNode看上去像父節(jié)點(diǎn)
Posted on 2006-07-18 09:57 肖鵬 閱讀(559) 評(píng)論(0) 編輯 收藏
0.引子
通常一個(gè)TreeNode (DefaultMutableTreeNode)如果沒有子結(jié)點(diǎn),它的節(jié)點(diǎn)顯示為不可展開的節(jié)點(diǎn),有時(shí)候我們希望即使該節(jié)點(diǎn)暫時(shí)沒有裝載子結(jié)點(diǎn)仍然顯示為可展開的節(jié)點(diǎn)(如圖
)。比如,當(dāng)加載子結(jié)點(diǎn)比較耗時(shí)或者需要?jiǎng)討B(tài)刷新,可以延時(shí)加載子結(jié)點(diǎn),即在展開節(jié)點(diǎn)的時(shí)候再去裝載子結(jié)點(diǎn)。
1.由來及解決方案
該屬性取決于,DefaultTreeModel的isLeaf方法?
通常一個(gè)TreeNode (DefaultMutableTreeNode)如果沒有子結(jié)點(diǎn),它的節(jié)點(diǎn)顯示為不可展開的節(jié)點(diǎn),有時(shí)候我們希望即使該節(jié)點(diǎn)暫時(shí)沒有裝載子結(jié)點(diǎn)仍然顯示為可展開的節(jié)點(diǎn)(如圖

1.由來及解決方案
該屬性取決于,DefaultTreeModel的isLeaf方法?
??? /** * Returns whether the specified node is a leaf node. * The way the test is performed depends on the * <code>askAllowsChildren</code> setting. * * @param node the node to check * @return true if the node is a leaf node * * @see #asksAllowsChildren * @see TreeModel#isLeaf */ publicboolean isLeaf(Object node) { if(asksAllowsChildren) return !((TreeNode)node).getAllowsChildren(); return ((TreeNode)node).isLeaf(); }而asksAllowsChildren由方法setAsksAllowsChildren設(shè)定
??? /** * Sets whether or not to test leafness by asking getAllowsChildren() * or isLeaf() to the TreeNodes. If newvalue is true, getAllowsChildren() * is messaged, otherwise isLeaf() is messaged. */ publicvoid setAsksAllowsChildren(boolean newValue) { asksAllowsChildren = newValue; }注意,在setRoot時(shí)可以只設(shè)定一次
?????? model.setRoot(root); /* * Since nodes are added dynamically in this application, the only true * leaf nodes are nodes that don't allow children to be added. (By * default, askAllowsChildren is false and all nodes without children * are considered to be leaves.) * * But there's a complication: when the tree structure changes, JTree * pre-expands the root node unless it's a leaf. To avoid having the * root pre-expanded, we set askAllowsChildren *after* assigning the * new root. */ model.setAsksAllowsChildren(true);
而在調(diào)用model.nodeStructureChanged(node)前后要分別設(shè)置為false和true。這是因?yàn)閚odeStructureChanged會(huì)自動(dòng)的試圖展開節(jié)點(diǎn)node,如果isLeaf返回為false。試想,asksAllowsChildren返回true,則一個(gè)結(jié)點(diǎn)即使沒有子結(jié)點(diǎn),只要設(shè)置了allowsChildren,對(duì)應(yīng)的treeNodeModel的isLeaf就會(huì)返回true。然而當(dāng)自動(dòng)展開節(jié)點(diǎn)的時(shí)候發(fā)現(xiàn)并沒有子結(jié)點(diǎn),當(dāng)然就會(huì)把圖標(biāo)去掉了。而先把a(bǔ)sksAllowsChildren設(shè)為false,就不會(huì)去試圖展開該節(jié)點(diǎn),然后設(shè)為true,該節(jié)點(diǎn)就會(huì)顯示為
。???
??? /** * Determines whether or not this node is allowed to have children. * If <code>allows</code> is false, all of this node's children are * removed. * <p> * Note: By default, a node allows children. * * @param allows true if this node is allowed to have children */ publicvoid setAllowsChildren(boolean allows) { if (allows != allowsChildren) { allowsChildren = allows; if (!allowsChildren) { removeAllChildren(); } } }
node.removeAllChildren(); DefaultTreeModel model = (DefaultTreeModel) cardTreeView.getModel(); /* * To avoid having JTree re-expand the root node, we disable * ask-allows-children when we notify JTree about the new node * structure. */ model.setAsksAllowsChildren(false); model.nodeStructureChanged(node); model.setAsksAllowsChildren(true);