Table Column Adjuster
Posted by Rob Camick on November 10, 2008
JTable sets a default width for each TableColumn in the table. When designing the table you can alter this width by setting the preferred size of the table column. However this size is only going to be a best guess as to the real width of the column. The real width of the column will never be known until data has been loaded in the table. It would be nice to be able to alter the width of the columns so that all text in the cell is displayed.
Some tables contain static data and some contain dynamic data. So we will need the ability to change the column widths after data is initially loaded and the ability to alter columns widths as the user changes the data in the table. Well, the TableColumnAdjuster can handle both situations. There are four main methods that can be used to change the column widths:
- Adjust Column – adjust the width of the specified column
- Adjust Columns – adjust the width of all columns
- Restore Column – restore the width of the specified column
- Restore Columns – restore the width of all columns
To help the TableColumnAdjuster calculate the appropriate column width you can set the following properties:
- Column Header Included – use the width of the column header
- Column Data Included – loop through all the rows of the TableModel and find the cell renderer with the largest width
- Only Adjust Larger – only reset the column width if the calculated value is greater than the current width of the column.
The maximum width calculated using the above properties will be used for the column width. To provide default column widths you might use code like the following which will generate the table shown in the image:
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
TableColumnAdjuster tca = new TableColumnAdjuster(table);
tca.adjustColumns();
Above is an example of installing the column adjuster and using static adjustments. As mentioned earlier the TableColumnAdjuster also supports dynamic column adjusts using the following property:
- Dynamic Adjustment - changes to the TableModel will cause the adjustments to occur automatically. Updating a table cell will cause the column to be adjusted. Adding/removing rows will cause all columns to be adjusted.
The user may find the dynamic adjustment a bit annoying if the width changes every time they type something, so we can also give the user to option to request column adjustments. This was done by adding Actions to the table which the user can invoke with the appropriate key stroke:
| Action | Key Stroke |
|---|---|
| Adjust Column | Control + |
| Adjust Columns | Control Shift + |
| Restore Column | Control - |
| Restore Columns | Control Shift - |
| Toggle Dynamic | Control * |
| Toggle Larger | Control / |
Note, that this class was designed to be used with tables that use an auto resize mode of AUTO_RESIZE_OFF. With all other modes you are constrained, as the width of the columns must fit inside the table. So if you increase the width of one column, the widths of one or more of the other columns must decrease. Because of this, the resize mode of RESIZE_ALL_COLUMNS will work the best.
Hopefully the usage of the static methods along with the user controlled Actions will provide the flexibility needed to adjust the width of any column in any situation.
Try The Demo
– Using Java™ Web Start (JRE 6 required)

Swapnil Devikar said
I have been looking for something like this for a while now.
It works like a charm!!
Thanks millions!!
Rob Camick said
Glad your searching lead you to this solution. Good luck.
lefameuxmarc said
Hello,
i was looking also for such class.
it fits perfectly my needs:)
Thank you very much
Rob Camick said
Glad it suits your needs.
Lionel said
Hello Rob,
The code worked absolutely perfectly upon implementation in my project. Thank you kindly for your effort and time spent to solve the same problem all us developers were struggling with!
I have placed your details in the script code in my application, for future reference.
Once again, thank you very much!
Regards,
Lionel
Rob Camick said
Good luck with the application.
Nirav said
Hi Rob,
You have done nice job here…Table column width setting is a main prob. in application..
You gave here nice solution..but i have found another solution which might be little simple to understand than this…
Kindly see it and tell me if its correct or some modification needed..
it is here
http://niravjavadeveloper.blogspot.com/2011/05/resize-jtable-columns.html
Anonymous said
hiii
i don’t have jre6 but i really need this class
can i have a version with jdk1.5?
thanks a lot!
Rob Camick said
I don’t know what JDK6 specific code might be causing problems. You will need to modify the class yourself with a JDK5 solution.
John Paul Jai said
Hi Rob,
Thanks again!!! :)
I have one question – if we set the Table Header as null, i am getting exception
Rob Camick said
Instead of making the header null, make the header invisible:
Anonymous said
John,
then something is wrong which should be fixed, not hacked around (like in forcing the header into not showing, doooohhh).
Anonymous said
not anonymous, just forgot to sign ;-)
Cheers
Jeanette
Michael said
Rob, wow great class! I have modified it for my use. Among other things, I added a tableContainer member var and have a property that allows for expanding to the full container width (like JScrollPane) if it’s not already wider than the container (tricky since I want it to fill the container exactly so I have to size each column carefully). I also had to change your Map to be just a Map (column number and width key value pairs), and added some functionality to manage the Map since it didn’t allow for the change in number of columns and my table does that.
Rob Camick said
Glad you where able to customize the code for your requirement.
Matt said
Hey Michael that is exactly what I am trying to do as well however it doesn’t appear to be working for me. Another problem may be the fact that I have hidden columns in my table, but I would think that the table.convertColumnIndexToView(e.getColumn()); would handle that with a -1. Would you mind sharing your code?
Michael said
I have not tried hidden columns, but my table changes number of columns and all data as part of its main purpose. It does that with pretty much everything you do in the program. The table is really used for just display purposes, derived from something else. I don’t use convertColumnIndexToView.
I added a JScrollPane tableContainer member variable and put it in the constructor. I did the same with an int tableContainerExclusionZone to limit what space the table can encroach on because I have a row header in the left column that needed to be accounted for. Row headers are really a pain I’ve found since they’re not really supported in Swing like a column header is. That’s beyond me since plenty of tables have a header down the left (spreadsheets anyone?).
So after that, I made a new method adjustColumnsFillContainerWidth() that’s actually called at the end of the adjustColumns() method. That checks the current table width (that was made from normal adjustColumns()). Now the table would have already kept its max width if columns were added by the nature of how it works, but if columns decreased, it may no longer fill the space. So it calculates any leftover width that can be filled (container width minus table and exclusion zone), and expands it if needed by going through each column and adding width evenly. I have it getting all the widths to add for everything first, then does the adjustColumn() for each one.
I also needed to update the map holding the column widths to remove map elements if the number of columns was reduced. The adding of columns already worked via the map’s put method called in updateTableColumn().
Your hidden columns may require more work to make sure it fills the space. I’m not sure how it works but it may budget the space for that and not appear to take up the whole width. You would have to do an extra step to take that into account, on both adding and subtracting columns.
Dave said
So from my understanding here, if the table width is smaller than the visible viewport, the table won’t be stretched by the TableColumnAdjuster. I’ll try to achieve the same as Michael, but I’ll try a simpler approach (since all I want is to stretch small tables): if any leftover width (table is added to a jscrollpane), set the table to JTable.AUTO_RESIZE_ALL_COLUMNS.
What I am struggling at is how to know if there’s any leftover. Can you share the piece of code you wrote to achieve that?
Dave said
Alright, found what I wanted on Rob’s answer here: http://stackoverflow.com/a/15240806/468508
Michael said
Dave, yeah you found it. Actually for a minute I thought I was doing all this work when I could have just been using AUTO_RESIZE_ALL_COLUMNS on my table but no, that causes it to be useless when there are too many columns in a limited space. That’s what I was dealing with when I coded my stuff.
Thanks for replying back here with what you found!
“What I am struggling at is how to know if there’s any leftover.”
Well in case anyone is doing what I’m doing, here is the beginning of my method adjustColumnsFillContainerWidth() where it checks if there is leftover, and the helper it uses. The tableContainerExclusionZone is a var I added for the width of the part of the container that table should not encroach on since I have a row header in the first column as I mentioned above. You don’t need it if you don’t have a row header like me. The 2 is there since I just found that 2 pixels weren’t being accounted for, maybe a column margin or something but I ended up just using 2 after having trouble fiddling with that.
public void adjustColumnsFillContainerWidth(){ //only proceed if we're not filling the container's width currently int tableWidth = getTableWidth(); int tableContainerWidthMinusExcl = tableContainer.getWidth() - tableContainerExclusionZone - 2; if (tableWidth < tableContainerWidthMinusExcl){ //we have room to spare, need to expand into it .... } } public int getTableWidth() { int tableWidth = 0; for (int i = 0; i < columnSizes.size(); i++) tableWidth += (int) columnSizes.get(i); return tableWidth; }Wolv said
Exactly what i was looking for, thanks for sharing!
Rob Camick said
Good to know it does what you want.
Amani said
Thaaaaaank alot for your help … this is what I was looking for :)
Rob Camick said
Glad you found what you where looking for.
Taying said
YOU ROCK!
Anonymous said
Amazing dude… Nice work… with this class, adjust column width jtable is like piece of cake…. thanks^^
posting
Anonymous said
Very nice! This helped me a lot!
Rui Tomas said
Excelent class…
Should be included by default :)
Thanks
Anonymous said
thanks too!
Robert, googling for a solution just like that :-)
Jose San Pedro Miralles said
hi there, i found this googling, i tried on my project but arent working i guess. the columns stay the same as default after the adjustcolumns call. this works only when you type directly on the cell? im filling the table with data retreived from a database. you have any tips to make this work in my project? thanks!
Anonymous said
Thank you!
Are you releasing this with an open source license (BSD)?
Rob Camick said
The “About Page” says you are free to use/modify the code as you wish at your own risk.
Anonymous said
wow, someone finally plugged that hole in the JDK libraries :-)
thank you very very much for sharing it.
would you consider putting this code up on github or something so that people may submit any further enhancements they make to it?
Govind Koranga said
working excellent…
thank you very much…
Anonymous said
Dude! You are awesome! Saved me a boat load of time and effort. Thanks!
Anonymous said
I think the link is dead, can someone upload a new version?
Rob Camick said
Still works fine for me.
Anonymous said
Thank you! Great class as many have said. Any chance this makes it to github so stuff like filling the full container makes it into the shared codebase? And you never answered the license question. Currently I am not sure if it is even possible to use the code legally for anything.
Rob Camick said
The “About Page” says you are free to use/modify the code as you wish at your own risk.
Arild said
Very useful…. thanx alot… Havent found greater example.
Gian said
How can I implement it on custom coded model jTable?
private String[][] data;
private String[] header = {“Client Name”, “Contact No.”, “Gender”, “Unit”, “No. of Released”, “Date”};
DefaultTableModel model = new DefaultTableModel(data, header);
Rob Camick said
The TableColumnAdjuster is created for the table not the TableModel so your custom model is not an issue.
Gian said
Can you show me the step by step implementation process? I only know how to implement plugins.. Thank you :)
Rob Camick said
There is no implementation process. You just copy the code to your computer, compile the code and then use the code in your application.
Zekeriya Bars said
Thanks a lot for this very useful class !
Rob Camick said
Thanks for the feedback.
Anonymous said
Thanks a mil..