• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

JTree - Compare Nodes problem

 
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,

I am making a program that displays the contents of a JAR file in a JTree. The contents of the JAR are returned as an Enumeration<JarEntry> and each name has the full path of the file. Here is an example:

tree name string
+-folder1
| +-file1.txt folder1/file1.txt
+-folder2
+-folder3
| +-file2.txt folder2/folder3/file2.txt
| +-file3.txt folder2/folder3/file3.txt
+-file4.txt folder2/file4.txt

The problem I'm having is checking if a node already exists in the tree. For example, folder3 has multiple files in it. When I get to file3.txt I want to find the node that folder 3 is at and add file3.txt as a child node to folder3. However, when I try to check if two nodes are equal, it always returns false unless the pointers point to the exact same node object. I've also tried the .equals(otherNode) method and I've tried comparing the UserObjects of the nodes too and still the same story.

I'm using the DefaultMutableTreeNode object for my nodes and a JTree for my tree. The UserObjects are strings defined at the instantiation of the node object. If you need more information or anything else just ask.

Thanks in advance for all your help guys.
 
Sheriff
Posts: 22849
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
DefaultMutableTreeNode doesn't override equals, so it still uses the Object way: using ==.

Create a subclass (or a complete new TreeNode implementation) that overrides equals to compare the object values.

I wrote a class that uses a SortedSet as a backing collection; if an "existing" child node was added to a node the two nodes were merged. It's not that complex to create a similar class yourself.
 
Author
Posts: 986
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Derek Boring:
I've tried comparing the UserObjects of the nodes too and still the same story.



What type of objects are you using for the user objects? These are under your control, so you should be able to control how equals() works on them.
 
Derek Boring
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks guys. I'm using string objects for the userobjects and I just figured out that the toString() method returns the string value, so I just compared those instead of the whatever the getUserObject() methods returned. Thanks for the help guys.

I now have another problem though. If this should be put into a new topic, just let me know.

I need to know how to clear all the nodes out of an entire tree without loosing the root node. (i.e. remove all children from the root node) I tried rootNode.removeAllChildren() but it doesn't work, all the children are still in the tree but no longer connected to the root node. Logically this seems to be the correct functionality for this method, but I want all the nodes except the root to be disposed of. After looking through some APIs it seems that the quickest way is to recreate the root node, but since you can only set the root node in the JTree's constructor, that requires recreating the JTree.

Is there a better way to do this? or do I need to modify my code to create a new JTree every time I want to clear it?
 
Brian Cole
Author
Posts: 986
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Derek Boring:
I need to know how to clear all the nodes out of an entire tree without loosing the root node. (i.e. remove all children from the root node) I tried rootNode.removeAllChildren() but it doesn't work, all the children are still in the tree but no longer connected to the root node. Logically this seems to be the correct functionality for this method



It's hard to know what to suggest without more details. For instance, are you using DefaultTreeModel or some other class?

One thing you can try: If you're using DefaultTreeModel make sure you are calling yourModel.insertNodeInto() and yourModel.removeNodeFromParent() and that you are not calling someNode.insert() or someNode.remove() or someNode.removeAllChildren().

You can also make sure the adding/removing of nodes happens on the event tread.

(That response was mostly copied from an older thread.)

Note that the DefaultTreeModel doesn't have a method analogous to removeAllChildren() so you have to iterate through the children to remove them all. It's more work, but it will fire the correct TreeModelEvents for the display to be updated correctly. Alternatively you can fire your own event after calling rootNode.removeAllChildren(). That's what you need to do if you're not using DefaultTreeModel (presuming I've guessed your problem correctly).
[ January 19, 2008: Message edited by: Brian Cole ]
 
Rob Spoor
Sheriff
Posts: 22849
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Derek Boring:
Is there a better way to do this? or do I need to modify my code to create a new JTree every time I want to clear it?


If your model is a DefaultTreeModel, it has a setRoot method which you can use. Then you call its nodeStructureChanged(TreeNode node) method, which will inform the view (JTree) that the structure for the root node has changed.
 
Derek Boring
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
All of my nodes are of type DefaultMutableTreeNode and soon will be node types that extend DefaultMutableTreeNode for custom functionality. What I was using is rootNode.removeAllChildren() This however leaves the nodes in the tree, they are just not connected to anything. It seems like what you guys are saying is I need something like this:



And then call:



Look correct?
 
Brian Cole
Author
Posts: 986
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Derek Boring:
I was using is rootNode.removeAllChildren() This however leaves the nodes in the tree, they are just not connected to anything.



No, it should actually remove the nodes (from the TreeModel). What it doesn't do is send an event to the JTree, so the JTree doesn't realize that it needs to redraw itself.

It seems like what you guys are saying is I need something like this:



That's not what I said. To do what I said you would replace the arrowed line with

((DefaultTreeModel)myTree.getTreeModel()).removeNodeFromParent(t);

Of course that won't work if your tree model isn't a DefaultTreeModel.


And then call:



Look correct?



You don't need this code at all if you do the DefaultTreeModel.removeNodeFromParent() above, because removeNodeFromParent() does fire off TreeModelEvents.

Otherwise the purpose of calling setRoot(myRoot), even though the root is already myRoot, is to force the JTree to update. There are other ways to do this, such as calling ((DefaultTreeModel)myTree.getTreeModel()).nodeStructureChanged(myRoot), if it is needed but setRoot() is probably easiest.
 
Derek Boring
Ranch Hand
Posts: 65
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, that helped alot. You guys are awesome!
reply
    Bookmark Topic Watch Topic
  • New Topic