![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.cuf.ui.table.OptimalColumnWidthSupport Maven / Gradle / Ivy
The newest version!
package net.sf.cuf.ui.table;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
/**
* Add-on for a {@link JTable} to easily set a table column to an optimal width.
* The optimal width is defined as the maximum length of the currently displayed header and table cell values.
* The setting of optimal colunm widths works best on tables with {@link JTable#AUTO_RESIZE_OFF}.
*
* This class offers two functionalities:
*
* - You can use the static method {@link #adjustToOptimalColumnWidth(JTable,int)} to set any column of any table
* to its optimal width.
* - You can bind an instance of this class to a table which will react on double clicks in the resize area
* between table columns to adjust the size of the left column. Only resizable columns will be changed
*
*
* @author Hendrik Wördehoff, sd&m AG
*/
public class OptimalColumnWidthSupport
extends MouseAdapter
implements PropertyChangeListener
{
/** Property name in {@link JTable}. */
private static final String TABLE_PROPERTY_TABLEHEADER = "tableHeader";
/** The table we work on. */
private JTable mTable;
/**
* Constructor.
* Registers this instance as a mouse listener for double clicks on the resize area oof the table header.
* Also registers as a property change listener in case the header of the table is changed.
* @param pTable table to work on
*/
public OptimalColumnWidthSupport(final JTable pTable)
{
if ( pTable == null )
throw new IllegalArgumentException("table must not be null");
this.mTable = pTable;
// register for mouse clicks in the pTable header
pTable.getTableHeader().addMouseListener(this);
// register for changes of the pTable header
pTable.addPropertyChangeListener(TABLE_PROPERTY_TABLEHEADER, this);
}
/**
* Disconnect from our table.
* Use this method if you need to get rid of this instance.
*/
public void dispose()
{
// remove listeners
mTable.getTableHeader().removeMouseListener(this);
mTable.removePropertyChangeListener(TABLE_PROPERTY_TABLEHEADER, this);
// break this instance
mTable = null;
}
/**
* Adjust the width of all columns of the table.
* @param pTable table to work on
* @throws IllegalArgumentException if table
is null
*/
public static void adjustToOptimalColumnWidth(final JTable pTable)
{
if ( pTable == null )
throw new IllegalArgumentException("table must not be null");
for (int i = 0; i < pTable.getColumnCount(); i++)
{
adjustToOptimalColumnWidth(pTable, i);
}
}
/**
* Adjust the width of a column.
* This method will do nothing if the index is not a valid column index.
* @param pTable table to work on
* @param pViewIndex view column index
* @throws IllegalArgumentException if table
is null
*/
public static void adjustToOptimalColumnWidth(final JTable pTable, final int pViewIndex)
{
if ( pTable == null )
throw new IllegalArgumentException("table must not be null");
if ( pViewIndex >= 0 && pViewIndex < pTable.getColumnCount() )
{
adjustToOptimalColumnWidth(pTable, pTable.getColumnModel().getColumn(pViewIndex));
}
}
/**
* Adjust the width of a column.
* As we can only be called from within this class we are sure that the column
belongs to
* this table
and is currently visible.
* @param pTable table to work on
* @param pColumn column to work on
*/
private static void adjustToOptimalColumnWidth(final JTable pTable, final TableColumn pColumn)
{
int modelIndex = pColumn.getModelIndex();
int viewIndex = pTable.convertColumnIndexToView(modelIndex);
int margin = pTable.getColumnModel().getColumnMargin();
// get header width
TableCellRenderer r = pColumn.getHeaderRenderer();
if ( r == null )
{
r = pTable.getTableHeader().getDefaultRenderer();
}
int width = determineCellWidth(r, pTable, pColumn.getHeaderValue(), -1, viewIndex);
// get largest column width
TableModel model = pTable.getModel();
for ( int row = 0; row < model.getRowCount(); row++ )
{
width = Math.max(width, determineCellWidth(pTable.getCellRenderer(row, viewIndex), pTable, model.getValueAt(row, modelIndex), row, viewIndex));
}
width += margin;
// take min and max widths in account
width = Math.max(width, pColumn.getMinWidth());
width = Math.min(width, pColumn.getMaxWidth());
// set width
pColumn.setWidth(width);
pColumn.setPreferredWidth(width);
// the following code is for some reasons necessary to get the change displayed properly
pTable.revalidate();
pTable.getTableHeader().resizeAndRepaint();
}
/**
* Get the width of a table cell which displays a certain value.
* @param pRenderer table cell renderer
* @param pTable table object
* @param pValue value to display in the renderer
* @param pRow table view row index
* @param pColumn table view column index
* @return the matching width
*/
private static int determineCellWidth(final TableCellRenderer pRenderer, final JTable pTable, final Object pValue, final int pRow, final int pColumn)
{
Component c = pRenderer.getTableCellRendererComponent(pTable, pValue, false, false, pRow, pColumn);
return c.getPreferredSize().width;
}
/**
* We need to notice when the table header is changed so that we can move the mouse listener to the new header.
* @param pEvent table header change event
*/
public void propertyChange(final PropertyChangeEvent pEvent)
{
((JTableHeader)pEvent.getOldValue()).removeMouseListener(this);
((JTableHeader)pEvent.getNewValue()).addMouseListener(this);
}
/**
* We react on the second mouse press to profit from {@link JTableHeader#getResizingColumn} which is no longer
* set when the mouse click event occurs.
* @param pEvent mouse event
*/
public void mousePressed(final MouseEvent pEvent)
{
if ( pEvent.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(pEvent) )
{
TableColumn column = mTable.getTableHeader().getResizingColumn();
if ( column != null )
{
adjustToOptimalColumnWidth(mTable, column);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy