/*
* Copyright (c) 2008, SQL Power Group Inc.
*
* This file is part of SQL Power Library.
*
* SQL Power Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* SQL Power Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ca.sqlpower.swingui.table;
import java.awt.Component;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
/**
* The TableUtils class contains simple static utility methods that are
* useful when working with JTable.
*/
public class TableUtils {
/**
* Sets the given column of the given table to be exactly as
* wide as it needs to be to fit its current contents. The contents
* of each body cell in this column, as well as the header component
* is taken into account.
*
* @param table The table whose column to resize
* @param colIndex The index of the column to resize
*/
public static void fitColumnWidth(JTable table, int colIndex, int padding) {
fitColumnWidth(table, colIndex, -1, padding);
}
/**
* Sets the given column of the given table to be exactly as
* wide as it needs to be to fit its current contents, but not exceeding
* a specified maximum. The contents
* of each body cell in this column, as well as the header component
* is taken into account.
*
* @param table The table whose column to resize
* @param colIndex The index of the column to resize
* @param maxWidth The maximum width, in pixels, that the column is allowed
* to have. Nonpositive values mean "no maximum."
*/
public static void fitColumnWidth(JTable table, int colIndex, int maxWidth, int padding) {
fitColumnWidths(table, -1, maxWidth, padding);
}
/**
* Sets the given column of the given table to be exactly as wide as it
* needs to be to fit its current contents, but not exceeding a specified
* maximum. The contents of each body cell in this column, as well as the
* header component is taken into account.
*
* @param table
* The table whose column to resize
* @param colIndex
* The index of the column to resize
* @param minWidth
* The minimum width, in pixels, that the column takes.
* Non-positive values means no minimum.
* @param maxWidth
* The maximum width, in pixels, that the column is allowed to
* have. Nonpositive values mean "no maximum."
*/
public static void fitColumnWidth(JTable table, int colIndex, int minWidth, int maxWidth, int padding) {
TableColumn column = null;
Component comp = null;
int cellWidth = 0;
TableCellRenderer headerRenderer =
table.getTableHeader().getDefaultRenderer();
column = table.getColumnModel().getColumn(colIndex);
comp = headerRenderer.getTableCellRendererComponent(
table, column.getHeaderValue(),
false, false, 0, colIndex);
// Headers need additional padding for some reason!
cellWidth = comp.getPreferredSize().width + 2;
int limit = table.getRowCount() > 100 ? 100 : table.getRowCount();
for (int j = 0; j < limit; j++) {
final TableCellRenderer cellRenderer = table.getCellRenderer(j,colIndex);
if (cellRenderer == null) continue;
comp = cellRenderer.getTableCellRendererComponent(table,
table.getValueAt(j, colIndex),false,false,j, colIndex);
// we add a one-pixel fudge factor here because the result is often too short by a pixel
cellWidth = Math.max(cellWidth, comp.getPreferredSize().width + 1);
if (maxWidth > 0 && cellWidth >= maxWidth) {
cellWidth = maxWidth;
break;
}
}
if (minWidth >= 0 && cellWidth < minWidth) {
cellWidth = minWidth;
}
column.setPreferredWidth(cellWidth + padding);
}
/**
* Makes each column of the given table exactly the right size it needs but
* not greater than the maxColumnWidth provided. To have no restraints on the
* maximum column size, pass in a negative number for maxColumnWidth. Note that
* this method turns the table auto resize off.
*
* @param table the table that will have its columns adjust to appropiate size
* @param maxColumnWidth specifies the maximum width of the column, if no
* maximum size are needed to be specified, pass in a negative number
* @param padding the number of pixels of extra space to leave (the actual column
* width will be the maximum width of any value in the column, plus this padding amount)
*/
public static void fitColumnWidths(JTable table, int maxColumnWidth, int padding) {
fitColumnWidths(table, -1, maxColumnWidth, padding);
}
/**
* Makes each column of the given table exactly the right size it needs but
* not greater than the maxColumnWidth provided and no less than the
* minColumnWidth provided. To have no restraints on the maximum or minimum
* column size, pass in a negative number for maxColumnWidth or
* minColumnWidth respectively. Note that this method turns the table auto
* resize off.
*
* @param table
* the table that will have its columns adjust to appropiate size
* @param maxColumnWidth
* specifies the maximum width of the column, if no maximum size
* are needed to be specified, pass in a negative number
* @param padding
* the number of pixels of extra space to leave (the actual
* column width will be the maximum width of any value in the
* column, plus this padding amount)
*/
public static void fitColumnWidths(JTable table, int minColumnWidth, int maxColumnWidth, int padding) {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
int limit = table.getColumnCount() > 5 ? 5 : table.getColumnCount();
for (int colIndex = 0; colIndex < limit; colIndex++) {
fitColumnWidth(table, colIndex, minColumnWidth, maxColumnWidth, padding);
}
}
/**
* Makes each column of the given table exactly the right size with no
* constraints on how big the column width would go
*
* @param table the table that will have its columns adjust to appropiate size
* @param padding the number of pixels of extra space to leave (the actual column
* width will be the maximum width of any value in the column, plus this padding amount)
*/
public static void fitColumnWidths(JTable table, int padding) {
fitColumnWidths(table, -1, padding);
}
/**
* Digs through any number of layers of TableModelWrapper to find the
* non-wrapper model at the bottom.
*
* @param m
* The table model to unwrap. You probably suspect it implementes
* TableModelWrapper.
* @return The first TableModel encountered which is not an instance of
* TableModelWrapper. If m itself is not a wrapper, m will be returned.
* @see TableModelWrapper#getWrappedModel()
*/
public static TableModel unwrap(TableModel m) {
while (m instanceof TableModelWrapper) {
m = ((TableModelWrapper) m).getWrappedModel();
}
return m;
}
/**
* Makes each column of the given table exactly the right width, so that the first and the last columns may have width
* values different from the middle ones.
* @param table the table that will have its columns adjust to appropriate size
* @param firstColumnWidth specifies the width of the first column
* @param middleColumnWidth specifies the width of the columns located between the first and the last ones
* @param lastColumnWidth specifies the width of the last column
* @param padding
* the number of pixels of extra space to leave (the actual
* column width will be the maximum width of any value in the
* column, plus this padding amount)
*/
public static void adjustColWidth(JTable table, int firstColumnWidth, int middleColumnWidth, int lastColumnWidth, int padding) {
int colCount = table.getColumnCount();
fitColumnWidth(table, 0, firstColumnWidth, firstColumnWidth, padding);
for(int i = 1; i < colCount-1; i++){
fitColumnWidth(table, i, middleColumnWidth, middleColumnWidth, padding);
}
fitColumnWidth(table, colCount-1, lastColumnWidth, lastColumnWidth, padding);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
}
}