Search code examples
swinguser-interfacetreejtree

Removing leaves that are between nodes in a JTree


enter image description here

Let's assume that I have a JTree similar to the picture I provided, in which the number of leaves and nodes will vary every time I run the code. Now how could I remove the nodes that are empty (AKA have no children) since I can't check so see if its going to be empty as I add them to the tree?

I have tried using an enumeration to traverse the tree and check for every node to check how many children it has but that didn't help because even if I could tell that the node I am at is a node that needs to be removed I have to tell his parent to remove him I cant tell him to remove himself from his parent node.

What do I need to use to achieve what I am looking for?


Solution

  • Now how could I remove the nodes that are empty...so i want a node to either have only other nodes or only leaves but not both at the same time

    Traverse the tree and check for nodes which have the following criteria

    1. Is a leaf
    2. Has siblings that are not leafs.

    even if I could tell that the node I am at is a node that needs to be removed I have to tell his parent to remove him I cant tell him to remove himself from his parent node.

    That is what the DefaultTreeModel.removeNodeFromParent() method does. So you can traverse the tree recursively and just remove nodes based upon your given criteria.

    DefaultMutableTreeNode root = new DefaultMutableTreeNode ("Root");
    //other code
    DefaultTreeModel treeModel = new DefaultTreeModel(root);
    JTree tree = new JTree(treeModel);
    //populate tree
    
    recurseTree(root, treeModel);
    
    //method to recursively remove leaf nodes that have non-leaf siblings
    private void recurseTree(MutableTreeNode node, DefaultTreeModel treeModel){
        if ( node.isLeaf() ){
            TreeNode parent = node.getParent();
            for ( int i = 0; i < parent.getChildCount(); i++ ){
                if ( !parent.getChildAt(i).isLeaf() ){
                    treeModel.removeNodeFromParent(node); 
                    break;
                }
            }
        }else{
            for ( int i = 0; i < node.getChildCount(); i++ ){
                recurseTree((MutableTreeNode)node.getChildAt(i), treeModel);
            }
        }
    
    }
    

    All this being said, it looks like a long route around the initial addition of those nodes. Without knowing the underlying data structure to populate the tree one can only guess as to how to go about preventing those nodes from being added in the first place.