Table Column Manager
Posted by Rob Camick on May 8, 2011
When using a JTable the user has some control over the view of the columns in the table. The columns can be resized and they can be reordered. One feature that is not supported is the ability to hide and reshow a column.
Hiding a column is easy. You can just remove the TableColumn from the TableColumnModel. The problem is reshowing the column. When you remove the column from the model you also lose all the information about the column. Information like:
- the text of the column. This is the heading that appears in the table header for the column
- the last known width of the column
- the last know position of the column in the view of the table
The solution to these problems is to use the TableColumnManager. The TableColumnManager will handle hide and show requests and then invoke the appropriate TableColumnModel method. Using this approach the manager is able to keep track of the necessary column information. Users have full control over the visibility of a column by using the popup menu that is installed on the table header. Right clicking on any column of the table header will show the popup containing all the columns managed by the TableColumnManager.
The code to add a TableColumnManager to the table shown in the image above was:
JTable table = new JTable( new DefaultTableModel(15, 10) );
TableColumnManager tcm = new TableColumnManager(table);
tcm.hideColumn("E");
Hopefully this will give the users a little more flexibility when using tables.
Get The Code
TableColumnManager.java
TableColumnManagerDemo.java
Santhosh Kumar T said
when all columns are removed, there is no way to get them back. This is because TableHeader is not visible with zero columns.
Support for grouping columns could be taken as enhancement. for example in taskmanager, users wishing to analize memory would like to toggle all columns related to memory (ex: private memory, real memory, shared memory) to be toggled by single click.
Rob Camick said
Oops, code has been changed, you can no longer remove the last column.
Grouping of columns would be an interesting enhancement. I’ll have to give that some though as to how that might be handled.
Thanks.
Nirav said
Hi,
this is very helpful,
but how to manage the width of the column, as per the data in it. Do you know..?
Rob Camick said
This is not a forum for answering general questions. But you are lucky as I have an entry called “Table Column Adjuster” that should help you out.
Nirav said
ok Rob,
Actually i am not aware of that..but this entry called “Table Column Adjuster” is helpful to me…now i am working on it…
Thanks..
mjquake said
i just wanted to say it again!, your table manipulation classes are way beyond awesome, thanks a million.
Rob Camick said
Glad you find the table ideas helpful.
mjquake said
Hi Rob,
Do you happen to have anything on printing jtables.
Rob Camick said
Just a link to a tutorial. Read the JTable API and follow the link to the tutorial on using tables. From there take a look at the table of contents and you will find a section on “How to Print Tables”.
mjquake said
sure thanks
Google said
Excellent work. Always works.
Rob Camick said
Good to hear.
Anonymous said
Thanks! This is exactly what I’ve been searching for!
maheeka said
brilliant work!! Thanks.
Rob Camick said
Thanks for the feedback
Brad K. said
I used this and it works great. Hoever, I tried to use a Robot mouseMove(x,y) function to put the mouse cursor on the menu element (me[1] in your code). The cursor-relocation works, but pretty regularly when doing this and actually selecting the checkbox to deselect/hide the column, my program throws a bunch of “ArrayIndexOutOfBoundsException: -1” exceptions afterwards when JTable goes and accesses DefaultTableColumnModel.getColumn()=>Vector.elementAt(). Any ideas as to why? It works fine without the automatic cursor relocation.
Rob Camick said
I would try to wrap your code that repositions the mouse pointer in a SwingUtilities.invokeLater(). This will allow the original code to execute completely before repositioning the mouse pointer. Thats all I can think of. Good luck.
Brad K. said
Brilliant! That’s got it. I knew it was something I had done … I presumed that the SelectPopupMenu handler was running on the event dispatch thread, but then looking back at the actual code, I see that it, too, is running in a SwingUtilities.invokeLater(). Thanks for all of your quality examples!
Brad K. said
Ah, it is still happening, but less frequently. I’ll keep at it.
Wilson said
Very, Very nice, Thank you!!
bm said
Amazing work! Thank you! Thank you! Thank you!
Joseph mifsud said
Incredible piece of logic, Mr. Camick, I just plugged in the chunk of code into my application and it worked faultlessly.
One question though… how do you hide more than one columns though the code I mean not using the pop up?
Thank you very much… much indebted to you.
Joe
Joseph mifsud said
disregard the question just place as many ‘hideColumn(x)’ commands as one wishes, using an integer in my case however.
Thanks again
Anonymous said
very useful and work excellent. Thanks.