Breite von Tabellenspalten automatisch am Zelleninhalt anpassen

Aus Byte-Welt Wiki
(Weitergeleitet von AutofitTableColumns)
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() {
    }
}