Removing all selected nodes within a JTree

A "delete selected nodes" button invokes the following code when pressed:


DefaultTreeModel model = (DefaultTreeModel ) my_tree.getModel() ;
TreePath [] tps = my_tree.getSelectionPaths() ;

for ( int i=0; i<tps.length; i++ )
{
    MutableTreeNode node = (MutableTreeNode ) tps[i].getLastPathComponent() ;
    model.removeNodeFromParent( node ) ;
}


However, I get a ClassCastException on this line:

    DefaultTreeModel model = (DefaultTreeModel ) getModel() ;


Why is this?

Could it be anything to do with the fact that I'm assigning a custom TreeModel when I instantiate my JTree ?


Thanks.
LVL 25
InteractiveMindAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
>>Could it be anything to do with the fact that I'm assigning a custom TreeModel when I instantiate my JTree ?

Yes. See what type it is:

System.out.println(my_tree.getModel().getClass());
0
InteractiveMindAuthor Commented:
public class FileTreeModel implements TreeModel, Serializable, Cloneable
{ .. }
0
CEHJCommented:
Ah *that* one ;-) That won't support removal of nodes as is. That would need adaptation to something like a subclass of DefaultTreeModel
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

InteractiveMindAuthor Commented:
Ah right;

so, I've extended DefaultTreeModel... but I need to pass a TreeNode to the super's constructor... what would that need to be?
0
CEHJCommented:
That'd need to be a TreeNode based on the directory tree root
0
InteractiveMindAuthor Commented:
Okay, here's what I've tried:

    super( new DefaultMutableTreeNode( new File( "C:\\" ) ) ) ;

It's no longer giving me any errors when I cast getModel() to DefaultTreeModel.


However, I get the following exception:

    java.lang.ClassCastException: java.io.File

on this line:

    MutableTreeNode node = (MutableTreeNode ) tps[i].getLastPathComponent() ;


I'm guessing that due to my node's being File's, that getLastPathComponent() is returning a File object ?

But a File object doesn't seem to be highly useful for me here... how can I fix this ??
0
CEHJCommented:
You need to arrange it so that every node of the tree has a userObject of type File. It's not sufficient just to fix the root node
0
InteractiveMindAuthor Commented:
All nodes within the tree are File objects.
0
CEHJCommented:
You need to make them of the same type as the root node you just created
0
InteractiveMindAuthor Commented:
Hm, how would I do that?

Here's my tree model as things stand:


import javax.swing.* ;
import javax.swing.tree.* ;
import javax.swing.event.* ;
import java.awt.Component ;
import java.awt.event.* ;
import java.util.* ;
import java.io.* ;

public class FileTreeModel extends DefaultTreeModel implements Serializable, Cloneable
{
      
      // V A R I A B L E S
      
      protected EventListenerList listeners ;
      private static final Object LEAF = new Serializable() {} ;
      private Map map ;
      private File root ;
      
      
      // C O N S T R U C T O R
      
      public FileTreeModel( File root )
      {
            super( new DefaultMutableTreeNode( new File( "C:\\" ) ) ) ;
            
            this.root = root ;

            if ( !root.isDirectory() )
                  map.put( root, LEAF ) ;

            this.listeners = new EventListenerList() ;

            this.map = new HashMap() ;
      }
      
      
      // P U B L I C   M E T H O D S
      
      public Object getRoot()
      {
            return root ;
      }

      public boolean isLeaf( Object node )
      {
            return map.get( node ) == LEAF ;
      }

      public int getChildCount( Object node )
      {
            List children = children( node ) ;

            if ( children == null )
                  return 0 ;

            return children.size() ;
      }

      public Object getChild( Object parent, int index )
      {
            return children( parent ).get( index ) ;
      }

      public int getIndexOfChild( Object parent, Object child )
      {
            return children( parent ).indexOf( child ) ;
      }
      
      protected List children( Object node )
      {
            File f = (File ) node ;

            Object value = map.get( f ) ;

            if ( value == LEAF )
                  return null ;

            List children = (List ) value ;

            if ( children == null )
            {
                  File [] c = f.listFiles() ;

                  if ( c != null )
                  {
                        children = new ArrayList( c.length ) ;

                        for ( int len = c.length, i = 0 ; i < len ; i++ )
                        {
                              children.add( c [i] ) ;
                              if ( !c [i].isDirectory() )
                                    map.put( c [i], LEAF ) ;
                        }
                  } else
                        children = new ArrayList( 0 ) ;
                  
                  
                  map.put( f, children ) ;
            }

            return children ;
      }

      public void valueForPathChanged( TreePath path, Object value )
      {}

      public void addTreeModelListener( TreeModelListener l )
      {
            listeners.add( TreeModelListener.class, l ) ;
      }

      public void removeTreeModelListener( TreeModelListener l )
      {
            listeners.remove( TreeModelListener.class, l ) ;
      }
      
      
      public Object clone()
      {
            try
            {
                  FileTreeModel clone = (FileTreeModel ) super.clone() ;

                  clone.listeners = new EventListenerList() ;

                  clone.map = new HashMap( map ) ;

                  return clone ;
            } catch ( CloneNotSupportedException e )
            {
                  throw new InternalError() ;
            }
      }
      
}

0
CEHJCommented:
Looks like in the children method, you need to get that Map arranged to have DefaultMutableTreeNode as its keys and List of the same as its values. The nodes, of course, will be initialized with File
0
InteractiveMindAuthor Commented:
Hm.

Here's what I'm trying to achieve (as you've probably guessed):

The user can delete a node within the file tree - which deletes the corresponding file on the hard drive, and also removes the selected node (of course).

I was just thinking.... would it be easier to just delete the selected file (I can do this bit), and then refresh the tree model?

I know how to refresh the tree model, as to update it (so, in effect, the deleted file's node also dissappears)... However, when I refresh the tree model, all of the expanded nodes collapse.. Is there a way of recording which nodes have been expanded, and then just re-expanding them after the tree model has been refreshed?
0
CEHJCommented:
The simplification is possible and probably desirable, but there's a possibilty you may run into problems by not having 'real nodes' further down the line.

You could record the expansions and restore them later:

http://java.sun.com/docs/books/tutorial/uiswing/events/treeexpansionlistener.html
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
InteractiveMindAuthor Commented:
Yer, I'll do that. :)

Cheers CEHJ.
0
CEHJCommented:
:-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.