# JTree - alle Nodes entfernen



## Taneeda (19. Feb 2009)

Hallo zusammen,

Ich habe da ein Problem mit einem JTree. Im Laufe meiner Applikation werden in einen JTree mehrere Einträge gemacht. Dabei läuft alles standardäßig ab, d.h. DefaultMutableTreeNode, DefaultTreeModel... nur der Renderer hab ich selbst gemacht.

Mein Problem: Ich möchte die Einträge, die in diesen JTree gemacht wurden entfernen, leider funktioniert das nicht richtig. Bisher benutze ich die Methode removeAllChildren(). Wenn ich nun aber neue Nodes zum Baum hinzufüge, werden die alten aber trotzdem angezeigt, wie kann das sein?

Aus dem FAQ bin ich auch nicht schlau geworden und auch sonst hab ich bisher nichts hilfreiches finden können, oder ich habe es schlicht übersehen...


----------



## manuche (19. Feb 2009)

Ich weiss jetzt nicht was in der Doku steht aber wie wärs wenn du dir einfach einen neuen JTree erzeugst...

z.B.:
	
	
	
	





```
this.alterTree = new JTree(...);
```

So wird der alte Baum komplett in die Tonne getreten und der GarbageCollector kümmert sich um den Rest!


----------



## Taneeda (19. Feb 2009)

Ja, das wäre wohl ne Möglichkeit, is aber nun nicht wirklich sauber ^^

abgesehen davon, müsste ich diesen dann erneut zur GUI hinzufügen, da hab ich auch keine Lust zu, scheint mir etwas zu viel Aufwand um einen Baum zu leeren


----------



## manuche (19. Feb 2009)

Vielleicht nicht das non-plus-ultra aber bevor ich mich mühsam darum kümmere den Tree aufzuräumen hau ich das Ding lieber komplett weg ^^
Irgendwelche Kollisionen gehst du damit auf jeden Fall aus dem Weg


----------



## Taneeda (19. Feb 2009)

hab das eben mal probiert. Hab die alte Referenz auf null gesetzt und nen neuen JTree erstellen lassen. Wenn ich in der Gui jetz aber auf den clear Button klicke, dann passiert nichts. Ich kann den Baum weiter normal auf und zuklappen, mit allen Einträgen... erst wenn neue Einträge hinzugefügt werden sollen, dann leert sich der Baum, neue Einträge werden aber nicht hinzugefügt.

Weiß jemand, wie man das sauber lösen kann, also wie man wirklich die Nodes vom JTree löschen kann?


----------



## MarcB (19. Feb 2009)

Mach nach dem leeren mal ein 
	
	
	
	





```
((DefaultTreeModel)tree.getModel()).reload()
```


----------



## Taneeda (19. Feb 2009)

bringt auch nichts...


----------



## Taneeda (19. Feb 2009)

hier mal mein Code...

die Klasse Tree ist nur ein Wrapper um einen JTree

```
package client.view.guicomponents;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;

/**
 * @brief This class creates a JTree, used in Error/Failure window for 
 * errors and failures.
 * 
 * @author Ronald
 */
public class Tree
{
    /**
     * Generated serial.
     */
    private static final long serialVersionUID = 1983919987487092942L;

    /**
     * This is the tree which holds the objects as his childs.
     */
    private JTree tree = null;
    
    /**
     * A default tree model.
     */
    private DefaultTreeModel dtmodel = null;
    
    /**
     * A node in the tree. This is the root node.
     */
    private DefaultMutableTreeNode root = null;
    
    /**
     * Signals the tree that he should expand automatic.
     */
    private boolean autoExpand = true;
    
    /**
     * An empty default constructor.
     */
    public Tree()
    { }
    
    /**
     * This constructor initializes the JTree with an array.
     * 
     * @param projects The array.
     */
    public Tree(Object[] projects)
    {
        if(tree == null)
        {
            tree = new JTree(projects);
            tree.setModel(getDefaultTreeModel());
        }
    }
    
    /**
     * Creates a JTree if not exist an returns his reference to the caller.
     * 
     * @return The reference to the JTree.
     */
    public JTree getJTree()
    {
        if(tree == null)
        {
            tree = new JTree(getDefaultTreeModel());
        }
        
        return tree;
    }
    
    /**
     * Initializes the tree with an array of objects. This method is used
     * by the workplace tree, because this tree need to initializes with
     * custom data. Also the workplace tree doesn't use the 
     * DefaultTreeModel.
     * 
     * @return void
     */
    public void initTree()
    {
        tree = new JTree();
    }
    
    /**
     * Initializes the tree with an array of objects. This method is used
     * by the workplace tree, because this tree need to initializes with
     * custom data. Also the workplace tree doesn't use the 
     * DefaultTreeModel.
     * 
     * @param projects The array with the objects.
     * @return void
     */
    public void initTree(Object[] projects)
    {
        tree = new JTree(projects);
    }
    
    /**
     * Sets the cell renderer for this Tree to cr.
     * 
     * @return void
     */
    public void setRenderer(TreeCellRenderer cr)
    {
        getJTree().setCellRenderer(cr);
    }
    
    /**
     * Creates a new model to the tree if not existing and returns the
     * reference to the caller.
     * 
     * @return The reference to the tree model.
     */
    public DefaultTreeModel getDefaultTreeModel()
    {
        if(dtmodel == null)
        {
            dtmodel = new DefaultTreeModel(getRootNode());
        }
        
        return dtmodel;
    }
    
    /**
     * Adds the Object obj to the Node to.
     * 
     * @param to    The Node which will contain the obj.
     * @param obj    The Object which will be added to node to.
     * @return void
     */
    public void addNode(DefaultMutableTreeNode to, 
        DefaultMutableTreeNode obj)
    {
        getDefaultTreeModel().insertNodeInto(
            obj, 
            to,
            getRootNode().getChildCount());
    }
    
    /**
     * Creates the root node of the JTree and returns the reference.
     * 
     * @return The reference to the root node of the JTree.
     */
    public DefaultMutableTreeNode getRootNode()
    {
        if(root == null)
        {
            root = new DefaultMutableTreeNode();
        }
        
        return root;
    }
    
    /**
     * Returns the auto expand setting to the caller.
     * 
     * @return The auto expand setting.
     */
    public boolean getAutoExpand()
    {
        return autoExpand;
    }
    
    /**
     * Delivers the Object name to the root node.
     * 
     * @param name The Object used in the root node.
     * @return void
     */
    public void setTreeName(String name)
    {
        getRootNode().setUserObject(name);
    }
    
    /**
     * Signals the client that he should expand automatically or not.
     * By default, auto expand is set to true.
     * 
     * @param aexp    The new auto expand setting.
     * @return void
     */
    public void setAutoExpand(boolean aexp)
    {
        autoExpand = aexp;
    }
}
```

in der Klasse GuiProgramArea, wird ein CloseableTabbedPane eingefügt, ein erster Tab mit einem Panel erstellt, dass den Tree beinhaltet


```
/**
     * Creates a new tabbed pane for the program area and the xml viewer
     * and returns the reference to the caller.
     * 
     * @return The reference to the tabbed pane.
     */
    public CloseableTabbedPane getJTabbedPane()
    {
        if(tabbedPane == null)
        {
            tabbedPane = new CloseableTabbedPane();
            tabbedPane.addTab
            (
                "Log", 
                new ImageIcon(getClass().getClassLoader().getResource(
                    IconLocations.ICON_APP_MAIN_TREE_PM_ROOT)), 
                getJPanelProgram()
            );
        }
        
        return tabbedPane;
    }
```


```
/**
     * This is the text pane for the program prints.
     * 
     * @return The handle to the JPanel.
     */
    private JPanel getJPanelProgram()
    {
        if(jPanelProgram == null)
        {
            jPanelProgram = new JPanel(new BorderLayout());
            jPanelProgram.setBorder(BorderFlags.loweredEtched);
            jPanelProgram.add(new PAControlPanel(), BorderLayout.NORTH);
            jPanelProgram.add(getTreeLog().getJTree());
            jPanelProgram.add(getJScrollPaneProgram());
        }
        
        return jPanelProgram;
    }
```


```
/**
     * Creates a new Tree if not existing.
     * 
     * @return The handle to the Tree.
     */
    public Tree getTreeLog() 
    {
        if(treeLog == null) 
        {
            treeLog = new Tree();
            treeLog.setTreeName("Program messages");
            treeLog.setRenderer(new TreeRendererProgram());
        }
        
        return treeLog;
    }
```

die bisherige Methode um den Tree zu leeren...

```
/**
     * This method clears the program tree by removing all entries.
     * 
     * @return void
     */
    public void clearProgramTree()
    {
        firstFileMessageReceived = false;
        firstNotifyMessageReceived = false;
        firstStandardMessageReceived = false;
        firstStatusMessageReceived = false;
        firstThmMessageReceived = false;
        
        numberFileMessages = 0;
        numberNotifyMessages = 0;
        numberStandardMessages = 0;
        numberStatusMessages = 0;
        numberThmMessages = 0;
        
        TreePath root = getTreeLog().getJTree().getPathForRow(0);
        getTreeLog().getJTree().collapsePath(root);
        
        int childsFileTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeFileMessages());
        for(int i=0; i<childsFileTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeFileMessages().getChildAt(i));
        }
        treeFileMessages = null;
        
        int childsNotifyTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeNotifyMessages());
        for(int i=0; i<childsNotifyTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeNotifyMessages().getChildAt(i));
        }
        treeNotifyMessages = null;
        
        int childsStandardTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeStandardMessages());
        for(int i=0; i<childsStandardTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeStandardMessages().getChildAt(i));
        }
        treeStandardMessages = null;
        
        int childsStatusTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeStatusMessages());
        for(int i=0; i<childsStatusTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeStatusMessages().getChildAt(i));
        }
        treeStatusMessages = null;
        
        int childsThmTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeThmMessages());
        for(int i=0; i<childsThmTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeThmMessages().getChildAt(i));
        }
        treeThmMessages = null;
        
        int childsRootTree = getTreeLog().getDefaultTreeModel().
            getChildCount(getTreeLog().getRootNode());
        for(int i=0; i<childsRootTree; i++)
        {
            getTreeLog().getDefaultTreeModel().removeNodeFromParent(
                (MutableTreeNode)getTreeLog().getRootNode().getChildAt(i));
        }
        
        getTreeLog().getDefaultTreeModel().reload();
        
//        getTreeLog().getRootNode().removeAllChildren();
//        getTreeFileMessages().removeAllChildren();
//        getTreeNotifyMessages().removeAllChildren();
//        getTreeStandardMessages().removeAllChildren();
//        getTreeStatusMessages().removeAllChildren();
//        getTreeThmMessages().removeAllChildren();
        
        getTreeLog().getJTree().revalidate();
        getTreeLog().getJTree().repaint();
        
        getJPanelProgram().revalidate();
        getJPanelProgram().repaint();
    }
```

ich weiß einfach nicht, wo der Fehler liegt


----------



## Taneeda (19. Feb 2009)

Ok, jetz funktionierts. lag wohl daran, dass das root node nicht richtig referenziert war... für alle interessierten, hier der korrigierte Code.

in Klasse Tree hinzufügen

```
/**
     * Sets the root node of the tree to.
     * 
     * @param root The new root node.
     * @return void
     */
    public void setRootNode(DefaultMutableTreeNode root)
    {
        this.root = root; 
    }
```
clearProgramTree()

```
/**
     * This method clears the program tree by removing all entries.
     * 
     * @return void
     */
    public void clearProgramTree()
    {
        firstFileMessageReceived = false;
        firstNotifyMessageReceived = false;
        firstStandardMessageReceived = false;
        firstStatusMessageReceived = false;
        firstThmMessageReceived = false;
        
        numberFileMessages = 0;
        numberNotifyMessages = 0;
        numberStandardMessages = 0;
        numberStatusMessages = 0;
        numberThmMessages = 0;
        
        TreePath root = getTreeLog().getJTree().getPathForRow(0);
        getTreeLog().getJTree().collapsePath(root);
        
        getTreeLog().getDefaultTreeModel().setRoot(null);
        getTreeLog().getDefaultTreeModel().setRoot(
            new DefaultMutableTreeNode("Program messages"));
[B] getTreeLog().setRootNode((DefaultMutableTreeNode)getTreeLog().
            getDefaultTreeModel().getRoot());[/B]
        getTreeLog().setRenderer(new TreeRendererProgram());
        getTreeLog().getJTree().updateUI();
        
        treeFileMessages = null;
        treeNotifyMessages = null;
        treeStandardMessages = null;
        treeStatusMessages = null;
        treeThmMessages = null;
        
        getTreeLog().getJTree().revalidate();
        getTreeLog().getJTree().repaint();
        
        getJPanelProgram().revalidate();
        getJPanelProgram().repaint();
    }
```


----------

