Breite von Tabellenspalten automatisch am Zelleninhalt anpassen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen

Oftmals möchte man, dass sich die Breite von von Tabellenspalten (JTable) automatisch an den (längsten) Zellinhalt anpasst.
Dieser im folgenden vorgestellte Java-Code demonstriert, wie man ein solches Verhalten erreichen kann:

/*
 * AutofitTableColumns.java
 * @author: omcgovern
 * 23.06.2007 added "fit"-option: uhrand (André Uhres)
 */

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.table.*;

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) {
        return (autoResizeTable(aTable, includeColumnHeaderWidth, columnPadding, false));
    }
    /*
     * @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
     * @param boolean fit, if you want the whole visible Area to be used
     * @returns The table width, just in case the caller wants it...
     */

    public static int autoResizeTable(JTable aTable, boolean includeColumnHeaderWidth, int columnPadding, boolean fit) {
        // NOTE: the "fit"-option has been added by uhrand
        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, true, 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();
            Dimension headerDim = tableHeader.getPreferredSize();
            // headerDim.height = tableHeader.getHeight();
            headerDim.width = tableWidth;
//            tableHeader.setPreferredSize( headerDim );//commented out by uhrand (caused resize bug)
            Dimension interCellSpacing = aTable.getIntercellSpacing();
            Dimension dim = new Dimension();
            int rowHeight = aTable.getRowHeight();
            if (rowHeight == 0) {
                rowHeight = 16;    // default rowheight
            }
            dim.height = headerDim.height + ((rowHeight + interCellSpacing.height) * aTable.getRowCount());
            dim.width = tableWidth;
            // aTable.setPreferredSize ( dim );
            int viewWidth = currentTableWidth;          //uhrand
            Component parent = aTable.getParent();      //uhrand
            if (parent instanceof JViewport) {            //uhrand
                JViewport port = (JViewport) parent;     //uhrand
                viewWidth = port.getExtentSize().width; //uhrand
            }                                           //uhrand
            if (fit && tableWidth != viewWidth) {         //uhrand
                int corr = (viewWidth - //uhrand
                        tableWidth) / columnCount;      //uhrand
                tableWidth = 0;                         //uhrand
                for (int i = 0; i < columnCount; i++) {  //uhrand
                    columnWidth[i] += corr;             //uhrand
                    tableWidth += columnWidth[i];       //uhrand
                }                                       //uhrand
                if (tableWidth != viewWidth) {            //uhrand
                    columnWidth[columnCount - 1] += //uhrand
                            (viewWidth - tableWidth);   //uhrand
                    tableWidth = viewWidth;             //uhrand
                }                                       //uhrand
            }                                           //uhrand
            TableColumnModel tableColumnModel = aTable.getColumnModel();
            TableColumn tableColumn;
            for (int i = 0; i < columnCount; i++) {
                tableColumn = tableColumnModel.getColumn(i);
//                System.out.println(tableColumn.getHeaderValue()+" "+columnWidth[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 maximum Column Width
     */

    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 (final ClassCastException ce) {
                    // Can't work out the header column width..
                    maxWidth = 0;
                }
            }
        }
        TableCellRenderer tableCellRenderer;
        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);
    }

    private AutofitTableColumns() {
    }
}