/*
* Found at http://forum.java.sun.com/thread.jspa?forumID=54&messageID=2532529&threadID=527301
* Author: omcgovern (http://forum.java.sun.com/profile.jspa?userID=358507)
* Note: A few patches were made to the original to honor 'includeColumnHeaderWidth'
and not to crash with null table header.
*/
package esmska.utils;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Component;
import javax.swing.text.JTextComponent;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableCellRenderer;
public class AutofitTableColumns
{
private static final int DEFAULT_COLUMN_PADDING = 5;
/*
* @param JTable aTable, the JTable to autoresize the columns on
* @param boolean includeColumnHeaderWidth, use the Column Header width as a minimum width
* @returns The table width, just in case the caller wants it...
*/
public static int autoResizeTable ( JTable aTable, boolean includeColumnHeaderWidth )
{
return ( autoResizeTable ( aTable, includeColumnHeaderWidth, DEFAULT_COLUMN_PADDING ) );
}
/*
* @param JTable aTable, the JTable to autoresize the columns on
* @param boolean includeColumnHeaderWidth, use the Column Header width as a minimum width
* @param int columnPadding, how many extra pixels do you want on the end of each column
* @returns The table width, just in case the caller wants it...
*/
public static int autoResizeTable ( JTable aTable, boolean includeColumnHeaderWidth, int columnPadding )
{
int columnCount = aTable.getColumnCount();
int currentTableWidth = aTable.getWidth();
int tableWidth = 0;
Dimension cellSpacing = aTable.getIntercellSpacing();
if ( columnCount > 0 ) // must have columns !
{
// STEP ONE : Work out the column widths
int columnWidth[] = new int [ columnCount ];
for ( int i=0; i<columnCount; i++ )
{
columnWidth[i] = getMaxColumnWidth ( aTable, i, includeColumnHeaderWidth, columnPadding );
tableWidth += columnWidth[i];
}
// account for cell spacing too
tableWidth += ( ( columnCount - 1 ) * cellSpacing.width );
// STEP TWO : Dynamically resize each column
// try changing the size of the column names area
JTableHeader tableHeader = aTable.getTableHeader();
if (tableHeader != null) {
Dimension headerDim = tableHeader.getPreferredSize();
// headerDim.height = tableHeader.getHeight();
headerDim.width = tableWidth;
tableHeader.setPreferredSize(headerDim);
}
Dimension interCellSpacing = aTable.getIntercellSpacing();
Dimension dim = new Dimension();
int rowHeight = aTable.getRowHeight();
if ( rowHeight == 0 )
rowHeight = 16; // default rowheight
// System.out.println ("Row Height : " + rowHeight );
dim.height = aTable.getPreferredSize().height + ( ( rowHeight + interCellSpacing.height ) * aTable.getRowCount() );
dim.width = tableWidth;
// System.out.println ("AutofitTableColumns.autoResizeTable() - Setting Table size to ( " + dim.width + ", " + dim.height + " )" );
// aTable.setPreferredSize ( dim );
TableColumnModel tableColumnModel = aTable.getColumnModel();
TableColumn tableColumn;
for ( int i=0; i<columnCount; i++ )
{
tableColumn = tableColumnModel.getColumn ( i );
tableColumn.setPreferredWidth ( columnWidth[i] );
}
aTable.invalidate();
aTable.doLayout();
aTable.repaint();
}
return ( tableWidth );
}
/*
* @param JTable aTable, the JTable to autoresize the columns on
* @param int columnNo, the column number, starting at zero, to calculate the maximum width on
* @param boolean includeColumnHeaderWidth, use the Column Header width as a minimum width
* @param int columnPadding, how many extra pixels do you want on the end of each column
* @returns The table width, just in case the caller wants it...
*/
private static int getMaxColumnWidth ( JTable aTable, int columnNo,
boolean includeColumnHeaderWidth,
int columnPadding )
{
TableColumn column = aTable.getColumnModel().getColumn ( columnNo );
Component comp = null;
int maxWidth = 0;
if ( includeColumnHeaderWidth )
{
TableCellRenderer headerRenderer = column.getHeaderRenderer();
if ( headerRenderer != null )
{
comp = headerRenderer.getTableCellRendererComponent ( aTable, column.getHeaderValue(), false, false, 0, columnNo );
if ( comp instanceof JTextComponent )
{
JTextComponent jtextComp = (JTextComponent)comp;
String text = jtextComp.getText();
Font font = jtextComp.getFont();
FontMetrics fontMetrics = jtextComp.getFontMetrics ( font );
maxWidth = SwingUtilities.computeStringWidth ( fontMetrics, text );
}
else
{
maxWidth = comp.getPreferredSize().width;
}
}
else
{
try
{
String headerText = (String)column.getHeaderValue();
JLabel defaultLabel = new JLabel ( headerText );
Font font = defaultLabel.getFont();
FontMetrics fontMetrics = defaultLabel.getFontMetrics ( font );
maxWidth = SwingUtilities.computeStringWidth ( fontMetrics, headerText );
}
catch ( ClassCastException ce )
{
// Can't work out the header column width..
maxWidth = 0;
}
}
}
TableCellRenderer tableCellRenderer;
// Component comp;
int cellWidth = 0;
for (int i = 0; i < aTable.getRowCount(); i++)
{
tableCellRenderer = aTable.getCellRenderer ( i, columnNo );
comp = tableCellRenderer.getTableCellRendererComponent ( aTable, aTable.getValueAt ( i, columnNo ), false, false, i, columnNo );
if ( comp instanceof JTextComponent )
{
JTextComponent jtextComp = (JTextComponent)comp;
String text = jtextComp.getText();
Font font = jtextComp.getFont();
FontMetrics fontMetrics = jtextComp.getFontMetrics ( font );
int textWidth = SwingUtilities.computeStringWidth ( fontMetrics, text );
maxWidth = Math.max ( maxWidth, textWidth );
}
else
{
cellWidth = comp.getPreferredSize().width;
// maxWidth = Math.max ( headerWidth, cellWidth );
maxWidth = Math.max ( maxWidth, cellWidth );
}
}
return ( maxWidth + columnPadding );
}
}