Java Swing - Automatically resize the JTable columns based on its values

I know that this problem I solved using before GWT-Ext, and now the time has come to make public the source code, which performs exactly the same thing 'auto-resize of the column based on the length of values from within the cells', but using Java Swing.

Below, there are defined 2 static functions that will do the trick (first one is public and call-able ddirectly in your code; the second one is a helper for the first one).

/**
 * Sets the table column width (column width = lenOfChars * 8)
 */
public static void resizeTable(JTable table, boolean... onlyIfBigger) {
    if (table != null) {
        boolean resized = false;
        int resizeMode = table.getAutoResizeMode();
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        int tw = 0;
        int size = table.getColumnCount();
        for (int col = 0; col < size; col++) {
             String longerValue = "";
             int longerRow = 0;
             for (int row = table.getRowCount(); --row >= 0;) {
                 Object value = table.getValueAt(row, col);
                 String val = (value == null ? "" : "" + value);
                 if (val != null && val.length() > longerValue.length()) {
                      longerValue = val;
                      longerRow = row;
                 }
            }
            tw += setTableColumnWidth(table, tw, longerRow, col, onlyIfBigger);
            if (tw != 0) {
                resized = true;
            }
       }

       if (!resized) {
           table.setAutoResizeMode(resizeMode);
       }

       int prefWidth = 0;
       TableColumnModel tcm = table.getColumnModel();

       for (int i = 0; i < tcm.getColumnCount(); i++) {
           TableColumn tc = tcm.getColumn(i);
            prefWidth += tc.getPreferredWidth();
       }

        int prefHeigh = table.getModel().getRowCount() * table.getRowHeight();
        table.setPreferredScrollableViewportSize(new Dimension(prefWidth, prefHeigh));
   }
}


/** Sets the table column width (column width = lenOfChars * 8) */
private static int setTableColumnWidth (JTable table, int currWidth, int longerRow, int column,
                                                            boolean... onlyIfBigger) {
    if (table != null) {
        TableColumnModel cm = table.getColumnModel();
        TableColumn colVal = cm.getColumn(column);

         if (table.getRowCount() == 0) {
             return 0;
         }
         boolean last_column = false;
         if (cm.getColumnCount() - 1 == column) {
             last_column = true;
         }

        Object value = table.getValueAt(longerRow, column);
        TableCellRenderer tcr = table.getCellRenderer(longerRow, column);
        Component c = tcr.getTableCellRendererComponent(table, value, false, false, longerRow, column);
        if (c instanceof JLabel) {
            value = ((JLabel) c).getText();
        }

        String longerValueStr = (value == null ? "" : "" + value);
        FontMetrics fm = table.getFontMetrics(c.getFont());
         int width1 = c.getPreferredSize().width + 6;
         int width2 = fm.stringWidth(longerValueStr) + 12;
         int width3 = 0;

         String header = (String) colVal.getHeaderValue();
         try {
             tcr = colVal.getHeaderRenderer();
             Component hc = tcr.getTableCellRendererComponent(table, header, true, true, 0, column);
             if (hc instanceof JButton) {
                 JButton bb = new JButton(header);
                 width3 = bb.getPreferredSize().width + 16;
            } else {
                 width3 = hc.getPreferredSize().width;
             }
         } catch (Exception e) {
             width3 = fm.stringWidth(header == null ? "" : header);
         }

         int width = Math.max(Math.max(width1, width2), width3);
         int oldLen = colVal.getPreferredWidth();
         int w = oldLen;


         if (onlyIfBigger.length > 0 && onlyIfBigger[0]) {
             if (width > oldLen) {
                  w = width;
             }
        } else {
             if (width != oldLen) {
                  w = width;
             }
         }


         if (last_column) {
               int orig_tw = table.getPreferredScrollableViewportSize().width;
               if (orig_tw - currWidth > w) {
                    w = orig_tw - currWidth;
              }
         }

         colVal.setPreferredWidth(w);
         return w;
    }
    return 0;
}

I hope it helped, even if the Swing development is on a descendant trend ... there are still some developers left out there.

Cheers!

No comments:

Post a Comment