2013-03-04 5 views
10

Ich habe eine benutzerdefinierte JTree und eine benutzerdefinierte JModel; Ich würde für den JTree "automatisch erweitern", wenn ich ihm ein neues Modell gebe. Im Moment kollabieren einfach alle Knoten mit der Wurzel.Wie erweitere ich automatisch einen JTree, wenn ich ein neues TreeModel einstelle?

Hier ein Beispiel:

private class CustomTree extends JTree { 

    @Override 
    public boolean isExpanded(TreePath path) { 
     return ((Person) path.getLastPathComponent).hasChildren(); 

} 

private class CustomTreeModel extends TreeModel { 

    // ... omitting various implementation details 

    @Override 
    public boolean isLeaf(Object object) { 
     return !((Person) object).hasChildren(); 
    } 

} 

Model model = new Model(); 
Person bob = new Person(); 
Person alice = new Person(); 
bob.addChild(alice); 
model.setRoot(bob); 
JTree tree = new CustomTree(new CustomTreeModel(model)); 

An diesem Punkt zeigt der Baum richtig:

- BOB 
    - ALICE 

wo Alice ein Kind von Bob ist (sowohl in den Daten und in der visuellen Struktur)

Allerdings, wenn ich rufe:

tree.setModel(new CustomTreeModel(model)); 

alles ist zusammengebrochen:

+ BOB 

Gibt es eine Möglichkeit, „Auto-expand“ alles in dem Baum, wenn ein neues Modell?

+0

keine Ideen aus diesem Code und Beschreibung sind alle Anmeldern & Zuhörer gehen weg nach Modell geändert wird, – mKorbel

+0

@mKorbel Ich glaube, unter meine Antwort meine löst Problem. – sdasdadas

+0

:-) ............... benutze nicht index von int, du kannst diesen index verlieren, musst alle accessible über node inc speichern. Objektwert (meine Ansicht) – mKorbel

Antwort

13

Ich hatte ein ähnliches Problem.

Ihre Lösung (wie gepostet https://stackoverflow.com/a/15211697/837530) schien für mich nur für die Top-Level-Knoten zu arbeiten.

Aber ich musste alle a Nachkommen Knoten erweitern. So löste ich es mit der folgenden rekursiven Methode:

private void expandAllNodes(JTree tree, int startingIndex, int rowCount){ 
    for(int i=startingIndex;i<rowCount;++i){ 
     tree.expandRow(i); 
    } 

    if(tree.getRowCount()!=rowCount){ 
     expandAllNodes(tree, rowCount, tree.getRowCount()); 
    } 
} 

, die mit

expandAllNodes(tree, 0, tree.getRowCount()); 

aufgerufen wird, wo tree ist ein JTree.

Es sei denn jemand hat eine bessere Lösung.

+0

dies funktioniert nur für die oberen 3 Ebenen:/ – mattymanme

22

Die folgenden für mich gearbeitet (genannt nach dem neuen Modell Einstellung):

for (int i = 0; i < tree.getRowCount(); i++) { 
    tree.expandRow(i); 
} 
+0

@all: Diese Lösung ist ausreichend , hier ist keine Rekursion notwendig – ferkulat

+5

Wie für "warum": es funktioniert, weil 'expandRow()' mehr Zeilen anzeigen wird, wodurch 'getRowCount() 'nach jeder Erweiterung erhöht wird. Der Versuch, durch Speichern von 'n = getRowCount()' und 'for (i = 0; i Matthieu

8

Es gibt auch diese nicht rekursive Version.

private void expandAllNodes(JTree tree) { 
    int j = tree.getRowCount(); 
    int i = 0; 
    while(i < j) { 
     tree.expandRow(i); 
     i += 1; 
     j = tree.getRowCount(); 
    } 
} 
0

Da kann ich weder bearbeiten noch kommentiert die akzeptierte Antwort des letzte Frage des OP zu beantworten:

Gibt es eine Möglichkeit, „Auto-expand“ alles in dem Baum, wenn ein neues Modell ?

die Struktur zu erweitern, nachdem ein neues Modell (wie gewünscht durch die OP) zugeordnet ist, außer Kraft setzen treeDidChange() in Ihrem benutzerdefinierten Baum:

@Override 
public void treeDidChange() { 
    super.treeDidChange(); 
    expandAllNodes(this, 0, getRowCount()); 
} 
1

dies für mich gearbeitet ..

import javax.swing.*; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.TreePath; 
import javax.swing.tree.TreeNode; 
import java.awt.*; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.util.Enumeration; 

public class JTreeNodeAutoExpandCollapse extends JFrame { 
    public JTreeNodeAutoExpandCollapse() throws HeadlessException { 
     initializeUI(); 
    } 

    private void initializeUI() { 
     setSize(200, 200); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); 
     DefaultMutableTreeNode chapter1 = new DefaultMutableTreeNode("Chapter 1"); 
     DefaultMutableTreeNode sub1 = new DefaultMutableTreeNode("1.1"); 
     DefaultMutableTreeNode sub2 = new DefaultMutableTreeNode("1.2"); 
     DefaultMutableTreeNode sub3 = new DefaultMutableTreeNode("1.3"); 
     DefaultMutableTreeNode sub31 = new DefaultMutableTreeNode("1.3.1"); 
     DefaultMutableTreeNode sub32 = new DefaultMutableTreeNode("1.3.2"); 

     root.add(chapter1); 
     chapter1.add(sub1); 
     chapter1.add(sub2); 
     chapter1.add(sub3); 
     sub3.add(sub31); 
     sub3.add(sub32); 

     final JTree tree = new JTree(root); 
     expandTree(tree, false); 

     JScrollPane pane = new JScrollPane(tree); 
     pane.setPreferredSize(new Dimension(200, 200)); 

     JPanel buttonPanel = new JPanel(new BorderLayout()); 
     JButton expandAll = new JButton("Expand All"); 
     expandAll.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       expandTree(tree, true); 
      } 
     }); 

     JButton collapseAll = new JButton("Collapse All"); 
     collapseAll.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       expandTree(tree, false); 
      } 
     }); 

     buttonPanel.add(expandAll, BorderLayout.WEST); 
     buttonPanel.add(collapseAll, BorderLayout.EAST); 

     getContentPane().setLayout(new BorderLayout()); 
     getContentPane().add(pane, BorderLayout.CENTER); 
     getContentPane().add(buttonPanel, BorderLayout.SOUTH); 
    } 

    private void expandTree(JTree tree, boolean expand) { 
     TreeNode root = (TreeNode) tree.getModel().getRoot(); 
     expandAll(tree, new TreePath(root), expand); 
    } 

    private void expandAll(JTree tree, TreePath path, boolean expand) { 
     TreeNode node = (TreeNode) path.getLastPathComponent(); 

     if (node.getChildCount() >= 0) { 
      Enumeration enumeration = node.children(); 
      while (enumeration.hasMoreElements()) { 
       TreeNode n = (TreeNode) enumeration.nextElement(); 
       TreePath p = path.pathByAddingChild(n); 

       expandAll(tree, p, expand); 
      } 
     } 

     if (expand) { 
      tree.expandPath(path); 
     } else { 
      tree.collapsePath(path); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new JTreeNodeAutoExpandCollapse().setVisible(true); 
      } 
     }); 
    } 
}