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:

<code=java> /*

* 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() {
   }

} </code=java>