1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * ident        "%Z%%M% %I%     %E% SMI"
  24  *
  25  * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
  26  * All rights reserved.
  27  */
  28 package com.sun.dhcpmgr.ui;
  29 
  30 import javax.swing.JTable;
  31 import javax.swing.table.*;
  32 import javax.swing.event.TableModelEvent;
  33 import java.awt.Component;
  34 import java.util.Date;
  35 
  36 import com.sun.dhcpmgr.data.IPAddress;
  37 import com.sun.dhcpmgr.data.ValidationException;
  38 
  39 /**
  40  * A subclass of Swing's JTable which automatically resizes its columns to
  41  * fit the data being displayed in them.
  42  */ 
  43 public class AutosizingTable extends JTable {
  44     Date aDate = null;
  45     IPAddress longIP = null;
  46     
  47     /**
  48      * Construct the table
  49      */
  50     public AutosizingTable() {
  51         super();
  52     }
  53 
  54     /**
  55      * Construct the table with the given model.
  56      * @param model the TableModel to be used.
  57      */
  58     public AutosizingTable(TableModel model) {
  59         super(model);
  60     }
  61     
  62     /**
  63      * The table has changed; we'll resize the columns to contain the new data
  64      * as best they can.
  65      */
  66     public void tableChanged(TableModelEvent e) {
  67         /*
  68          * Let JTable do its thing, which probably includes wiping out 
  69          * the old columns and creating new ones
  70          */
  71         super.tableChanged(e);
  72         TableModel model = getModel();
  73         if (model.getRowCount() == 0) {
  74             // No data, so just skip all the gymnastics
  75             return;
  76         }
  77         /*
  78          * Set column widths by first finding largest value in each column
  79          * and then sizing accordingly
  80          */
  81         for (int i = 0; i < getColumnCount(); ++i) {
  82             TableColumn col = getColumnModel().getColumn(i);
  83 
  84             // Get the width of the header for this column
  85             TableCellRenderer r = col.getHeaderRenderer();
  86             int headerWidth = 0;
  87             Component c;
  88             if (r == null)
  89                 r = getTableHeader().getDefaultRenderer();
  90             if (r != null) {
  91                 c = r.getTableCellRendererComponent(this, col.getHeaderValue(),
  92                     false, false, 0, 0);
  93                 headerWidth = c.getPreferredSize().width;
  94             }
  95             Object maxVal = null;
  96 
  97             if (model.getColumnClass(i) == String.class) {
  98                 // Column contains strings; find the longest one
  99                 String maxString = "";
 100                 for (int j = 0; j < model.getRowCount(); ++j) {
 101                     String s = (String)model.getValueAt(j, i);
 102                     if (s != null) {
 103                         if (maxString.length() < s.length()) {
 104                             maxString = s;
 105                         }
 106                     }
 107                 }
 108                 maxVal = maxString;
 109             } else if (model.getColumnClass(i) == IPAddress.class) {
 110                 // Column contains IP addresses; one long one is as good as any
 111                 if (longIP == null) {
 112                     try {
 113                         longIP = new IPAddress("222.222.222.222");
 114                     } catch (ValidationException ex) {
 115                         // This should never happen!
 116                     }
 117                 }
 118                 maxVal = longIP;
 119             } else if (model.getColumnClass(i) == Date.class) {
 120                 // Column contains dates; now is as good a time as any other.
 121                 if (aDate == null) {
 122                     aDate = new Date();
 123                 }
 124                 maxVal = aDate;
 125             }
 126             // Now compute the width of the cell containing the longest value
 127             c = getDefaultRenderer(
 128                 model.getColumnClass(i)).getTableCellRendererComponent(
 129                 this, maxVal, false, false, 0, i);
 130             int cellWidth = c.getPreferredSize().width;
 131 
 132             // Set preferred width to the greater of the header & cell widths
 133             col.setPreferredWidth(Math.max(headerWidth, cellWidth));
 134         }
 135         // Now force the resizing we just did to be displayed
 136         sizeColumnsToFit(-1);
 137 
 138         // Force header to repaint itself, otherwise it won't align correctly
 139         getTableHeader().resizeAndRepaint();
 140     }
 141 }