Dynamically modifying nodes in a JTree

First let me just say I hate JTrees. Now, let’s proceed.

When you first try to learn how to use a JTree, the examples you find will set up a tree, say with DefaultMutableTreeNodes, and then add them to the tree, which gets displayed. All neat and nice. Well thats crap, I say, because they don’t teach you anything, they just let you alone to figure things out. And when you try to use this level of understanding in the real world something strange happens. When you add the first child of a node like “node.add(childnode)”, it works, but when you add more children it doesn’t display properly. Whats maddening is that every diagnostic you could imagine will tell you that the nodes are there, it’s just that the JTree isn’t displaying them.

What you were never told, and SHOULD have been told, is that the JTree maintains a data model and a selection model separate from the actual data. This is because it allows you to remodel existing data structures into tree form without having to extend DefaultMutableTreeNode to create your tree node element. That allows you to display, as a tree, stuff that really isn’t a tree. Why you would want to do this is up to you. But for the rest of us, who just extend DefaultMutableTreeNode because it is the right thing to do at the time, we need to know this.

When I first ran into this error, I panicked and wondered what I did wrong. The first solution I found was a common one, but was actually quite useless to me (and, I suspect, many others) because of how I wanted to extend TreeNodes for my data structure, and why I wanted to do this. I’ll tell you that solution anyways. It’s to add the nodes like this:

DefaultTreeModel model = (DefaultTreeModel) jtree.getModel(); model.insertNodeInto( (DefaultMutableTreeNode) newnode, (DefaultMutableTreeNode) parentnode, parentnode.getChildCount());

Wow, huh? Who would have thought? And thats why I hate JTrees. And you know what, this is exactly the kind of crap Ruby people bring up when they say Java is bloated. But.. rather than being like everyone else and force you to adopt some twisted Java paradigm that doesn’t make sense, giving Ruby people more ammo, I will teach you a dirty little hack that works, and allows you to keep thinking the way you want to think about jtrees and data structures. So this is for both the 95% of us that will never need to display non-tree data as trees, and also for the 5% of us who are capable of beating ruby people at their own game.

Just call model.reload().

Yeah it’s that simple. All those jerks that tried to make you type
DefaultTreeModel model = (DefaultTreeModel) jtree.getModel(); model.insertNodeInto( (DefaultMutableTreeNode) newnode, (DefaultMutableTreeNode) parentnode, parentnode.getChildCount());

can be safely ignored. All you really need to do is

model.reload();

Okay, maybe yourtree.getModel().reload(), if you don’t keep a model lying around, but same basic thing. Simple, huh? What’s even better is that if you’re loading the information in from a save file or something, and you need to do a lot of .add() operations, you can get away with just .add()ing and it will likely take less processor time. Just model.reload() when you’re done and you’re good to go.

As mentioned this practically encourages you to store your tree data in extended DefaultMutableTreeNodes – since you will only need one copy of the data, ever, regardless of how many jtrees you want to use. Just call model.reload for each jtree. Hey, it’s better than calling insertNodeWhatever for every jtree each time you add a node, right? Of course it is.

Good luck out there 🙂

Advertisements

3 Responses

  1. Thanks for the TIP!

    I found lot’s of bullshit written in some forums, and the solution is so simple. also i saw very weird solutions in adding items to JTable, and after some work i managed get it to a sentence.

    Cheers!

  2. Ironically I first encountered the solution with reload(). The problem is, that the whole tree collapses, so you have to save your current expanded nodes and restore the state after the reload. Or you use the first “solution” witch maintains the current tree state.

  3. Awesome, truly awesome, i’ve been looking for this solution whole day, and then, out of nowhere, i found this article, very helpful, thanks a lot!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: