Skip to main content

Freezable JTables (are they extreme?)

Posted by elevy on January 4, 2009 at 7:47 PM PST

Finally, after about 7 months I get back into writing a new blog entry. I changed jobs, and it hasn

Related Topics >>


Eli, now you have completely disabled scrolling when navigating over the "gap". Piling one trick onto another to cover what the first broke usually is a never-ending story. The problem with the fake component is that now table.getVisibleRect is incorrect, that's bound to confuse collaborators - there'll always be yet another hole waiting just around the corner ;-) The multiple-table approach (done as cleanly as possible, which is _lots_ of work as others already mentioned) is the only way I know of so far that is half-way workable. Read the "half-way" as not extendable: next logical requirement would by frozen rows, meaning 4 tables ... and/or the frozen part docked at any of the borders ... and ... :-) CU Jeanette

@Jeanette I simply meant that there is a simpler technique to create fixed columns. Of course a lot more has to be done to make it work as a full blown component. Issues you describe are solvable, but I do wish that this functionality can be part of actual JTable or JXTable.

This has been an interesting discussion to read. I did a talk a few months ago to the Austin Java Users Group, where I used this as an example case for building a custom Swing component. I used the multiple tables in JScrollPane approach, with event listeners to handle most of the navigation and column resizing issues, and while I wouldn’t say it works perfectly, it does work quite well.:) I could have addressed even more but given the time constraints, I think I hit the most important issues. The talk is available online at: The approach in this blog in neat because it is dynamic, regrettably it doesn’t appear to handle the case where frozen columns are resized too well. Thanks, Alex asme kind of component available in J2ME...can u provide me with a sample code.. Regards

We actually did this at my old job as part of a trading application. We used a method similar to ERYZHIKOV, where we had 2 JTables representing the whole spreadsheet. We created a custom component that placed 2 JTables side by side, if the user has requested column freezing. The component handled sending events to both tables to synchronize scrolling and row selection. The user was even able to adjust the frozen columns' width, and the component would automatically resize the viewport. It was a lot of work though. I think we ended up writing close to 30 classes, maybe about 10 of them being the heaviest in terms of lines of code.

Jeanette, Thanks for your comments, I just released a newer version that addresses the issues you mentioned. Still there is a small problem, which is that after the user selects a cell, the scroll bars can be used to move the cell under my JLabel. I am pretty sure that this problem can be solved too. However, I am running out of time right now. Perhaps I will write another post explaining how I did the event management, and publishing the new code. For now, you can click again in the Java Web Start link, it will launch the latest version, and you can get the jar file to play with it as well. Thanks again, eL

Eryzhikov, definitions of "works perfectly" seem to differ widely Your approach (which is the usual hack and even recommended somewhere in the swing technical documentation) has severe problems, f.i. - need to be very careful to keep row properties (selection, row height, sorting) in synch - column selection is broken across header/main table - navigation across header and main table doesn't work at all In this (incomplete) list, typically the first can be handled with enough effort, the second isn't overly important most of the time but the last tends to be a show-stopper, mainly because the BasicTableUI is very stubborn to "adjustments" Cheers Jeanette

Much simpler solution is to put put a separate JTable with fixed columns as row header of the same scroll pane. Something like following: JViewport viewport = new JViewport(); viewport.setView(fixColumnTable); viewport.setPreferredSize(fixColumnTable.getPreferredSize()); scrollPane.setRowHeaderView(viewport); scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixColumnTable.getTableHeader()); This works perfectly for me.

Elie, interesting approach - though not really working (have been there ;-) One problem is the re-direct of mouseEvents on the frozen columns if they are "in reality" invisible. A kind of invers problem is cell-wise navigation which may or may not involve scrolling of a column under the fixed ones. One example to see the misbehaviour, scroll all the way to the right and click on the frozen - the focus rect isn't painted because ... well, the ui thinks we hit a cell which is below the fake. Another example, scroll all the way to the right, click on the last cell to make it the lead, then navigate by keyboard to the left: when we reach the frozen, nothing much happens except that the focus rect disappears, no scrolling to visible. Again, not much the ui can do as it thinks the lead is visible. Actually, my conclusion at the time had been that it's impossible to make work - would love to be proven wrong, of course :-) CU Jeanette