View Javadoc

1   package com.melloware.jukes.gui.view.component;
2   
3   import java.awt.Component;
4   import java.awt.Point;
5   import java.awt.Rectangle;
6   import java.awt.event.MouseAdapter;
7   import java.awt.event.MouseEvent;
8   
9   import javax.swing.JTable;
10  import javax.swing.table.JTableHeader;
11  import javax.swing.table.TableCellRenderer;
12  import javax.swing.table.TableColumn;
13  import javax.swing.table.TableColumnModel;
14  
15  /**
16   * In Windows Explorer, you can change the column width to fit the widest cell
17   * by double clicking on the column header separators.
18   * Use this TableHeader with your JTable to do something similar.
19   * <p>
20   * Copyright (c) 1999-2007 Melloware, Inc. <http://www.melloware.com>
21   * @author Emil A. Lefkof III <info@melloware.com>
22   * @version 4.0
23   */
24  public final class EnhancedTableHeader
25      extends JTableHeader {
26      private final JTable table;
27  
28      public EnhancedTableHeader(TableColumnModel cm, JTable table) {
29          super(cm);
30          this.table = table;
31          addMouseListener(new MouseAdapter() {
32                  public void mouseClicked(MouseEvent e) {
33                      doMouseClicked(e);
34                  }
35              });
36      }
37  
38      public int getRequiredColumnWidth(TableColumn column) {
39          int modelIndex = column.getModelIndex();
40          TableCellRenderer renderer;
41          Component component;
42          int requiredWidth = 0;
43          int rows = table.getRowCount();
44          for (int i = 0; i < rows; i++) {
45              renderer = table.getCellRenderer(i, modelIndex);
46              Object valueAt = table.getValueAt(i, modelIndex);
47              component = renderer.getTableCellRendererComponent(table, valueAt, false, false, i, modelIndex);
48              requiredWidth = Math.max(requiredWidth, component.getPreferredSize().width + 2);
49          }
50          return requiredWidth;
51      }
52  
53      /**
54       * Autosizes all columns to fit to width of their data.
55       */
56      public void autoSizeColumns() {
57          TableColumnModel tableColumnModel = table.getColumnModel();
58          int col_count = tableColumnModel.getColumnCount();
59  
60          for (int i = 0; i < col_count; i++) {
61              TableColumn col = tableColumnModel.getColumn(i);
62              col.setMinWidth(this.getRequiredColumnWidth(col));
63          }
64      }
65  
66      public void doMouseClicked(MouseEvent e) {
67          if (!getResizingAllowed()) {
68              return;
69          }
70          if (e.getClickCount() != 2) {
71              return;
72          }
73          TableColumn column = getResizingColumn(e.getPoint(), columnAtPoint(e.getPoint()));
74          if (column == null) {
75              return;
76          }
77          int oldMinWidth = column.getMinWidth();
78          column.setMinWidth(getRequiredColumnWidth(column));
79          setResizingColumn(column);
80          table.doLayout();
81          column.setMinWidth(oldMinWidth);
82      }
83  
84      private TableColumn getResizingColumn(Point p, int column) {
85          if (column == -1) {
86              return null;
87          }
88          Rectangle r = getHeaderRect(column);
89          r.grow(-3, 0);
90          if (r.contains(p)) {
91              return null;
92          }
93          int midPoint = r.x + (r.width / 2);
94          int columnIndex;
95          if (getComponentOrientation().isLeftToRight()) {
96              columnIndex = (p.x < midPoint) ? (column - 1) : column;
97          } else {
98              columnIndex = (p.x < midPoint) ? column : (column - 1);
99          }
100         if (columnIndex == -1) {
101             return null;
102         }
103         return getColumnModel().getColumn(columnIndex);
104     }
105 }