Skip to main content

Egads! An actual Swing Tree-Table!

Posted by timboudreau on June 3, 2008 at 3:36 AM PDT

Four years ago, I went on a hunt for best practices for doing tree table components in Swing. We had a tree-table component in NetBeans, whose maintenance was my never-ending nightmare and the biggest source of bugs on my bug list. It had been written, with the best of intentions, based on Scott Violet's Swing Connection article about how to quickly hack up a tree-table component in Swing (Scott's article was also written with the best of intentions, and I have no intention to ding him here - what he wrote does work for simple use-cases - a debugger is not a simple use-case).

When I canvassed folks who had done Swing tree-tables on our mailing lists, most of them were based on that article, as ours was. What I heard back varied between groans of pain and mad rabid howls of pain. There are a few things in that original tree table design that just don't work - not reliably, anyway. Sending events to an offscreen component as if it were on-screen and expecting it to behave sanely is just a really bad idea that happens to work if the look and feel is a subclass of BasicLookAndFeel, and other look and feel implementations have been tormented into supporting this abuse by all the evil Tree-Table implementations in the wild. But the bottom line is, a look-and-feel author would have to be slightly insane to code their TreeUI to behave as if it were a live component when it has no parent and obviously is not one. In other words, the fact that the JTree-as-cell-renderer design works at all is just an accident of how BasicLookAndFeel's TreeUI implementation was designed, which other look and feels inherited. Never mind trying to use said JTree as a cell renderer in a table (I once made a 400% performance improvement in our tired, tortured, hacked-up TreeTable just by having it translate the graphics context instead of repositioning - and thus causing a re-layout) is seriously abusing the component. Now try convincing said offscreen JTree that it has keyboard focus in order to get it to paint appropriately in its role as a cell renderer for another component. On all look and feels. On all platforms. Everywhere.

You see what I mean.

After doing that canvassing back in '04, it was obvious that Swing needed a real tree-table component. So I started to write one (and the layout cache classes JTree uses were very, very helpful - thanks, Scott!).

I started on it, got the basics working, and then moved back to the U.S., changed jobs and ended up travelling the world full-time teaching other people to write NetBeans modules - but it didn't leave time to finish up the Tree Table work. Thankfully, my former office-mate, David Strupl, picked up where I left off when he left Sun to work on Nokia's NetBeans RCP app for managing cellular telephone networks.

The really, really great news is: This week, Standa Aubrecht - who took over a bunch of the stuff when I left full-time development of NetBeans in '04 and amazed me with how quickly he was able to get going in a complex codebase - committed it into the main line of NetBeans sources yesterday. So anybody who gets a dev build of NetBeans as of today has a perfectly working Swing Tree Table component they can use (the class name is Outline - I borrowed the name from Apple's Cocoa library - it's a little less clunky than "tree table" but gets the point across). The JAR file is org.netbeans.swing.outline.jar. Usage is incredibly easy - you just provide a standard Swing TreeModel of whatever sort you like, and an additional RowModel that can be queried for the other columns contents, editability and so forth. And you never have to worry about cells painted half one color and half another because the tree-cell part got repainted after focus went to a popup menu. It actually works!

The real credit here goes to David and Standa for getting this thing production-worthy - I just was pissed-off enough at having a gargantuan list of unfixable bugs (well, fix it on one platform, break it on another, or leave it unfixed everywhere, or semi-fixed some places - pure evil if you hold the illusion that what we do is computer science) four years ago to get the ball rolling. They're the guys who delivered it.

I'm incredibly happy to see this finally be real and available not just to people writing NetBeans modules, but anybody doing GUI apps in Java. There has been a need for a real, reliable tree table component for Swing programmers for a long, long, long time. All hail David and Standa!

Related Topics >>

Comments

This is cool. I am using it in my project for a year. Some ...

This is cool. I am using it in my project for a year. Some suggestion. 1. Not all the applications need the sorting. In my project, some table does not need sorting or has some special requirements for sorting. That is why I want to turn off the sorting in outline. What I did is add an interface setSortingAllowed in class setSortingAllowed to disable it. The interface isSortingAllowed will return this flag. Of course, the override interface defined in OutlineColumn can be removed. 2. The outline table header does not take the system LF. Somebody in my team really want it on Windows. I changed this line of code in class ETableHeaderRenderer the file ETableColumn.java private TableCellRenderer headerRenderer = new JTable().getTableHeader().getDefaultRenderer(); Change to private TableCellRenderer headerRenderer = table.getTableHeader().getDefaultRenderer();

>>how about an article on how to use it?
see
http://blogs.sun.com/geertjan/entry/swing_outline_component

Aberrant: Today's daily NetBeans build should contain the relevant JAR file - easy to isolate and use and no dependencies on other NetBeans code. JohnR, wondering how many similar accidents are waiting to happen: Way too many. It's really easy to think you're depending on an API when actually you're depending on a detail of how that API was implemented. This is the stuff that makes careers for me and Jarda Tulach, teaching API design. I'm glad we're feeding our families, but it's a bit pathetic that the fairly simple degree of analysis needed to figure out if you're creating a big honking hole isn't a basic part of everyone's design process - I guess it's because most of the world hasn't figured out that they're designing APIs whether they like it or not...

aberrant: Downloading the sources would be best so you could debug into the code if needed, but you could also grab the precompiled binary JAR from NetBeans' Hudson build server.

Hi Tim,
This sounds great. Is there a precompilled jar I could download or should I build form the source?

actually, it's 'all hail tim and david!' i just moved the source code from one repository to another... standa

Wow-

"the fact that the JTree-as-cell-renderer design works at all is just an accident of how BasicLookAndFeel's TreeUI implementation was designed"

I wonder how many more such "accidents" are waiting to happen?

-JohnR

Is there an easy way to use this with nodes and an ExplorerManager, or is org.openide.explorer.view.TreeTableView still the way to go?

Your screenshot leaves a lot to be desired. You should update the article with a clean, large screenshot of what this new component looks like.

Hi Tim, - great news - the link to the prcompiled jar doesn't work - any chance of this component being given to the comunity for integration with a next java-release?

tomwheeler wrote: Downloading the sources would be best so you could debug into the code if needed

Is there any easy way to report (minor) bugs I have found?

I guess I should clarify my previous comment. It's not that I want to report a bug in the "this doesn't work" sense, but minor code issues.

For example, in this bit from Outline.java TableModel mdl = getModel(); if (mdl instanceof OutlineModel) { return (OutlineModel) getModel(); probably return (OutlineModel) mdl; was intended.

There is a discussion on SwingX projetct about this component. See details in here. Regards.

The fact I was referring to, is that all hyperlinks in all comments had been removed (probably due to the repeated spamming in one of them). This included the link under "SwingX" in hmichel's comment.

Cheers Jeanette

Hmm .. all references removed? Afraid of the competition ... ? Grinning, of course. A preview into a new SwingX JXTreeTable - inspired by this good break-through - is discussed over at the SwingLabs forum. Feedback highly welcome!

http://forums.java.net/jive/thread.jspa?threadID=43641&tstart=0

Jeanette

References removed? Don't know what you mean. I'm thrilled that some of this work is migrating into the SwingX tree table, where there is some hope that it will find its way one day into Swing itself! -Tim

How can i edit node by double click on it?

Hey! I was at the Netbeans Deep Dive Session at Manila and I saw you demonstrate the iReport Plugin on Netbeans. I have tried it and successfully made reports. My question is, how do I tell a jButton on my project to display the report once it is pressed? I know that I have to put some codes at the Event handler of the jButton but I don't know what to code. I saw a screencast on how it is done, but it didn't show what code I needed to write to be able to make a database connection. Sorry, Java is new for me and I am really relying on the IDE to get things done. The demo that I saw of you making it was fast and looks easy enough. Kindly help please... Thanks!

how about an article on how to use it?

Wow, this is really great new, Tim. This has been a HUGE problem for me for years also. Any thoughts of contributing this to SwingX or distributing the Outline jar file separately? It would be nice to have it in a more obvious/easier-to-get-to place than installing Netbeans and ripping a jar out. I guess you could also start a separate project as was done with your Wizard framework, but it really would be nice to have all this stuff in SwingX.

The reason is JXTreeTable is (or was at the time) based on the same fatally flawed design as the one Outline was written to replace. Using it would have simply been replacing one unfixable set of bugs with a new set we'd never be able to fix except by begging the maintainers of that to slap as many band-aids on their version as our old one had.

mrmorris, luano

I think they both are very similar in one aspect: Both will never make it into the standard Java release - where such a widget would belong.

In the extremely unlikely event that standard Java will get a tree widget expect it to be a completely different, third design.

Have been using JXTreeTable for years which also revolves around javax.swing.TreeModel and what one must assume, very similar UI delegates etc. to this org.netbeans.swing.Outline (not a very intuitive name) component. Is anyone aware of the differences between Swinglabs JXTreeTable control and this Outline one? To a naïve consumer this seems to be somewhat duplicated effort, considering they are both sponsored by Sun.

How does it compare to SwingLabs JXTreeTable - and for that matter why not use JXTreeTable?