In Windows Explorer, you can change the column width to fit the widest cell by double clicking on the column header separators.
Use this TableHeader with your JTable to do something similar.

1    import java.awt.*; 
2    import java.awt.event.*; 
3    import javax.swing.JTable; 
4    import javax.swing.table.*; 
5     
6    public class EnhancedJTableHeader extends JTableHeader { 
7        private JTable table; 
8     
9        public EnhancedJTableHeader(TableColumnModel cm, JTable table) { 
10           super(cm); 
11           this.table = table; 
12           addMouseListener(new MouseAdapter() { 
13               public void mouseClicked(MouseEvent e) { 
14                   doMouseClicked(e); 
15               } 
16           }); 
17       } 
18    
19       public void doMouseClicked(MouseEvent e) { 
20           if (!getResizingAllowed()) 
21               return; 
22           if (e.getClickCount() != 2) { 
23               return; 
24           } 
25           TableColumn column = getResizingColumn(e.getPoint(), 
26                                                  columnAtPoint(e.getPoint())); 
27           if (column == null) { 
28               return; 
29           } 
30           int oldMinWidth = column.getMinWidth(); 
31           column.setMinWidth(getRequiredColumnWidth(column)); 
32           setResizingColumn(column); 
33           table.doLayout(); 
34           column.setMinWidth(oldMinWidth); 
35       } 
36    
37       private int getRequiredColumnWidth(TableColumn column) { 
38           int modelIndex = column.getModelIndex(); 
39           TableCellRenderer renderer; 
40           Component component; 
41           int requiredWidth = 0; 
42           int rows = table.getRowCount(); 
43           for (int i = 0; i < rows; i++) { 
44               renderer = table.getCellRenderer(i, modelIndex); 
45               Object valueAt = table.getValueAt(i, modelIndex); 
46               component = 
47                   renderer.getTableCellRendererComponent(table, valueAt, 
48                                                          false, false, i, 
49                                                          modelIndex); 
50               requiredWidth = Math.max(requiredWidth, 
51                                        component.getPreferredSize().width + 2); 
52           } 
53           return requiredWidth; 
54       } 
55    
56       private TableColumn getResizingColumn(Point p, int column) { 
57           if (column == -1) { 
58               return null; 
59           } 
60           Rectangle r = getHeaderRect(column); 
61           r.grow(-3, 0); 
62           if (r.contains(p)) { 
63               return null; 
64           } 
65           int midPoint = r.x + r.width / 2; 
66           int columnIndex; 
67           if (getComponentOrientation().isLeftToRight()) { 
68               columnIndex = (p.x < midPoint) ? column - 1 : column; 
69           } else { 
70               columnIndex = (p.x < midPoint) ? column : column - 1; 
71           } 
72           if (columnIndex == -1) { 
73               return null; 
74           } 
75           return getColumnModel().getColumn(columnIndex); 
76       } 
77   }

Few things to note here:

  • When you double-click on a header separator, the column to the left gets resized.
  • The table’s auto resize mode settings are honored. So if you want a horizontal scrollbar to appear, set auto resize mode to AUTO_RESIZE_OFF
  • It is not a good idea to use this if your table model is dynamic and you load data from an external source dynamically.
  • If you are using a custom cell renderer, then the preferred size returned by the renderer should return the correct value

Comments:

If you're using a JTable whose data are stored in an expensive place, you could just calculate the width of the items on the screen currently.
# posted by Anonymous : 7/31/2004 12:37:05 PM
 
Yes good idea. Thanks for the suggestion.
This code (taken from http://javaalmanac.com/egs/javax.swing.table/IsVis.html) 
can be used to determine the visibility of a cell. I haven't used it, but there 
is no reason to believe it will not work.

// Assumes table is contained in a JScrollPane. Returns true iff the
// cell (rowIndex, vColIndex) is completely visible within the viewport.
public boolean isCellVisible(JTable table, int rowIndex, int vColIndex) {
if (!(table.getParent() instanceof JViewport)) {
return false;
}
JViewport viewport = (JViewport)table.getParent();

// This rectangle is relative to the table where the
// northwest corner of cell (0,0) is always (0,0)
Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);

// The location of the viewport relative to the table
Point pt = viewport.getViewPosition();

// Translate the cell location so that it is relative
// to the view, assuming the northwest corner of the
// view is (0,0)
rect.setLocation(rect.x-pt.x, rect.y-pt.y);

// Check if view completely contains cell
return new Rectangle(viewport.getExtentSize()).contains(rect);
}

# posted by Lokesh : 8/1/2004 08:51:18 PM
Advertisements