如何在jtree中search特定节点并使该节点扩展。

我有一个100个节点的jtree。 现在我想search该树中的特定节点,并使该节点扩展..? 我该如何解决这个问题?

在@ mkorbel的答案上​​进行扩展,并在“ 如何使用树”中进行讨论,您可以recursion地searchTreeModel并获取TreePath到生成的节点。 一旦你有所需的path ,很容易在树中显示它。

 tree.setSelectionPath(path); tree.scrollPathToVisible(path); 

附录:这是“获取TreePath ”的一种方法。

 private TreePath find(DefaultMutableTreeNode root, String s) { @SuppressWarnings("unchecked") Enumeration<DefaultMutableTreeNode> e = root.depthFirstEnumeration(); while (e.hasMoreElements()) { DefaultMutableTreeNode node = e.nextElement(); if (node.toString().equalsIgnoreCase(s)) { return new TreePath(node.getPath()); } } return null; } 

下面是一个如何在search中遍历树的例子:

  import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; public class TreeDemo extends JFrame implements ActionListener{ private static final long serialVersionUID = 1L; public JTree tree; public JButton button; public JTextField text; public TreeDemo() { button = new JButton("Enter search text below and click"); text = new JTextField(); button.addActionListener(this); tree = new JTree(); DefaultMutableTreeNode root = new DefaultMutableTreeNode( "Deck" ); DefaultMutableTreeNode itemClubs= new DefaultMutableTreeNode( "Clubs" ); addAllCard( itemClubs ); root.add( itemClubs ); DefaultMutableTreeNode itemDiamonds = new DefaultMutableTreeNode( "Diamonds" ); addAllCard( itemDiamonds ); root.add( itemDiamonds ); DefaultMutableTreeNode itemSpades = new DefaultMutableTreeNode( "Spades" ); addAllCard( itemSpades ); root.add( itemSpades ); DefaultMutableTreeNode itemHearts = new DefaultMutableTreeNode( "Hearts" ); addAllCard( itemHearts ); root.add( itemHearts ); DefaultTreeModel treeModel = new DefaultTreeModel( root ); tree = new JTree( treeModel ); JScrollPane scrollPane = new JScrollPane(tree); getContentPane().add(scrollPane, BorderLayout.CENTER); getContentPane().add(button, BorderLayout.NORTH); getContentPane().add(text, BorderLayout.SOUTH); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(375, 400); } public void addAllCard( DefaultMutableTreeNode suit ) { suit.add( new DefaultMutableTreeNode( "Ace" ) ); suit.add( new DefaultMutableTreeNode( "Two" ) ); suit.add( new DefaultMutableTreeNode( "Three" ) ); suit.add( new DefaultMutableTreeNode( "Four" ) ); suit.add( new DefaultMutableTreeNode( "Five" ) ); suit.add( new DefaultMutableTreeNode( "Six" ) ); suit.add( new DefaultMutableTreeNode( "Seven" ) ); suit.add( new DefaultMutableTreeNode( "Eight" ) ); suit.add( new DefaultMutableTreeNode( "Nine" ) ); suit.add( new DefaultMutableTreeNode( "Ten" ) ); suit.add( new DefaultMutableTreeNode( "Jack" ) ); suit.add( new DefaultMutableTreeNode( "Queen" ) ); suit.add( new DefaultMutableTreeNode( "King" ) ); } public final DefaultMutableTreeNode findNode(String searchString) { List<DefaultMutableTreeNode> searchNodes = getSearchNodes((DefaultMutableTreeNode)tree.getModel().getRoot()); DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(); DefaultMutableTreeNode foundNode = null; int bookmark = -1; if( currentNode != null ) { for(int index = 0; index < searchNodes.size(); index++) { if( searchNodes.get(index) == currentNode ) { bookmark = index; break; } } } for(int index = bookmark + 1; index < searchNodes.size(); index++) { if(searchNodes.get(index).toString().toLowerCase().contains(searchString.toLowerCase())) { foundNode = searchNodes.get(index); break; } } if( foundNode == null ) { for(int index = 0; index <= bookmark; index++) { if(searchNodes.get(index).toString().toLowerCase().contains(searchString.toLowerCase())) { foundNode = searchNodes.get(index); break; } } } return foundNode; } private final List<DefaultMutableTreeNode> getSearchNodes(DefaultMutableTreeNode root) { List<DefaultMutableTreeNode> searchNodes = new ArrayList<DefaultMutableTreeNode>(); Enumeration<?> e = root.preorderEnumeration(); while(e.hasMoreElements()) { searchNodes.add((DefaultMutableTreeNode)e.nextElement()); } return searchNodes; } public static void main(String[] args) { TreeDemo app = new TreeDemo(); app.setVisible(true); } public void actionPerformed(ActionEvent e) { String search = text.getText(); if(search.trim().length() > 0 ) { DefaultMutableTreeNode node = findNode(search); if( node != null ) { TreePath path = new TreePath(node.getPath()); tree.setSelectionPath(path); tree.scrollPathToVisible(path); } } } } 

我假设你的意思是你想find一个特定的string的节点,对不对? 其他的答案解释了如何使用枚举方法来做到这一点…(我相信他们都知道,在现实世界中,您还必须迎合具有所寻找的string的多个节点的可能性,等等。)

但是还有其他更性感的方法可以做到这一点。 例如,如果你把所有的节点都放在一个collection中( ArrayList等*),就像它们被插入到树中一样(并且当它们被删除时删除它们,包括明确地删除它们的所有后代)…如果你还实现了两个节点,如果它们与toString具有相同的结果(或者实现了一个Comparator ),那么这两个节点就被认为是“相等的”,那么您可以轻松地popupArrayList中匹配的实际节点(或多个节点)然后去

 tree.expandPath( new TreePath( node_found.getPath()) 

树的一个要点是,它实际上是节点的path (有时称为“面包屑”),它是任何给定节点的真正“身份”。 就显示的String值而言,这意味着您可能在相同的树中:

path:“彼得” – “派珀” – “腌” – “辣椒”
path:“烹饪专业” – “香料” – “辣椒”
path:“我的最爱” – “食物” – “调味品” – “辣椒”

所以说你想要search,然后select或突出显示这些“胡椒”节点之一…对于这条path上的每个元素都有一个“暴力”枚举方法并不是非常有效树越大,当然问题越严重)。

使用我的build议变得非常简单:从根目录开始,或者在任何地方开始,分割你的“面包屑”path,然后当你向下钻入树中时,在“高”节点上使用node.isNodeDescendant() ) (也就是那些远离根的地方),你已经find了(这里是3个“胡椒”节点):如果你想要上面的第一条path,你首先会find节点“彼得”,然后立即只有“胡椒”节点这可以满足isNodeDescendanttesting将产生你正在寻找的整个path。

*当然,某些forms的哈希集合会更有效率。 但是,只有在树中有成千上万个节点的情况下才能考虑这个问题。