All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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