home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / TableColumn.java < prev    next >
Text File  |  1998-02-26  |  20KB  |  647 lines

  1. /*
  2.  * @(#)TableColumn.java    1.24 98/02/02
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing.table;
  22.  
  23. import com.sun.java.swing.*;
  24. import com.sun.java.swing.border.*;
  25. import java.lang.Integer;
  26. import java.awt.Color;
  27. import java.awt.Component;
  28. import java.io.Serializable;
  29. import java.beans.PropertyChangeEvent;
  30. import java.beans.PropertyChangeListener;
  31.  
  32. /**
  33.  *  A <B>TableColumn</B> represents all the attributes of a column in a 
  34.  *  <B>JTable</B>, such as width, resizibility, minimum and maximum width.
  35.  *  In addition, the <B>TableColumn</B> also helps to determine how the JTable
  36.  *  interprets and displays the value objects from the TableModel in
  37.  *  the column.  This is done using the cellRenderer of the column.  For
  38.  *  example, the TableModel can give the table Boolean objects
  39.  *  for a column.  If the column's cellRenderer is a <B>JCheckBox</B> 
  40.  *  component then the table will be able
  41.  *  to show the Boolean value as a checkbox.  If the column's
  42.  *  cellEditor is set similarly the user will then be able to modify the cell
  43.  *  value using a <B>JCheckBox</B>. This pairing of source's value object with 
  44.  *  cell renders and editors gives the table a great deal of power and flexibility. 
  45.  *  Because the table does not need to know anything about the data being 
  46.  *  displayed, the user is free to customize it. 
  47.  *  <p>
  48.  *  The TableColumn stores the link between the columns in the <B>JTable</B> 
  49.  *  and the columns in the <B>TableModel</B>. This, the <I>modelIndex</I>, is the 
  50.  *  column in the TableModel which will be queried for the data values for the 
  51.  *  cells in this column. As the column moves around in the view this 
  52.  *  <I>modelIndex</I> does not change. 
  53.  *  <p>
  54.  *  It is also possible to specify renderers and editors on a per type basis 
  55.  *  rather than a per column basis - see the <I>setDefaultRenderer()</I> method 
  56.  *  in the <B>JTable</B>. This default mechanism is only used when the renderer (or 
  57.  *  editor) in the <B>TableColumn</B> is <I>null</I>. 
  58.  * <p>
  59.  * Warning: serialized objects of this class will not be compatible with
  60.  * future swing releases.  The current serialization support is appropriate 
  61.  * for short term storage or RMI between Swing1.0 applications.  It will
  62.  * not be possible to load serialized Swing1.0 objects with future releases
  63.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  64.  * baseline for the serialized form of Swing objects.
  65.  *
  66.  * @version 1.24 02/02/98
  67.  * @author Alan Chung
  68.  * @author Philip Milne
  69.  * @see TableColumnModel
  70.  * @see DefaultTableColumnModel
  71.  */
  72. public class TableColumn extends Object implements Serializable {
  73. //
  74. // Static Constants
  75. //
  76.  
  77.     /** Bound property name. */
  78.     public final static String COLUMN_WIDTH_PROPERTY = "columWidth";
  79.     /** Bound property name. */
  80.     public final static String HEADER_VALUE_PROPERTY = "headerValue";
  81.     /** Bound property name. */
  82.     public final static String HEADER_RENDERER_PROPERTY = "headerRenderer";
  83.     /** Bound property name. */
  84.     public final static String CELL_RENDERER_PROPERTY = "cellRenderer";
  85.  
  86. //
  87. //  Instance Variables
  88. //
  89.  
  90.     /**
  91.       * The index of the column in the model which is to be displayed by 
  92.       * this TableColumn. As columns are moved around in the view the 
  93.       * model index remains constant. 
  94.       */
  95.     protected int    modelIndex;
  96.  
  97.     /**
  98.      *  This object is not used internally by the drawing machinery of 
  99.      *  the JTable. Identifiers may be set in the TableColumn as as an 
  100.      *  optional way to tag and locate TableColumns. The table package does 
  101.      *  not modify or invoke any methods in these identifer objects other 
  102.      *  than the <I>equals</I> method which is used in the 
  103.      *  <I>getColumnIndex()</I> method in the <B>DefaultTableColumnModel</B>.  
  104.      */
  105.     protected Object    identifier;
  106.     
  107.     /** The width of the column */
  108.     protected int    width;
  109.  
  110.     /** The minimum width of the column */
  111.     protected int    minWidth;
  112.  
  113.     /** The maximum width of the column */
  114.     protected int    maxWidth;
  115.  
  116.     /** The renderer used to draw the header of the column */
  117.     protected TableCellRenderer    headerRenderer;
  118.  
  119.     /** The header value of the column */
  120.     protected Object        headerValue;
  121.  
  122.     /** The renderer used to draw the data cells of the column */
  123.     protected TableCellRenderer    cellRenderer;
  124.  
  125.     /** The editor used to edit the data cells of the column */
  126.     protected TableCellEditor    cellEditor;
  127.  
  128.     /** Resizable flag */
  129.     protected boolean    isResizable;
  130.  
  131.     /**
  132.      *  Counter used to disable posting of resizing notifications until the
  133.      *  end of the resize
  134.      */
  135.     transient protected int    resizedPostingDisableCount;
  136.     
  137.     /**
  138.      * If any PropertyChangeListeners have been registered, the
  139.      * changeSupport field describes them.
  140.      */
  141.     private java.beans.PropertyChangeSupport changeSupport;
  142.  
  143. //
  144. // Constructors
  145. //
  146.  
  147.     /**
  148.      * Creates an empty <B>TableColumn</B>. This is intended for the use
  149.      * of the serialization code.  <p>
  150.      * 
  151.      */
  152.     public TableColumn() {
  153.     this(0);
  154.     }
  155.  
  156.     /**
  157.      *  Creates and initializes an instance of <B>TableColumn</B> with 
  158.      *  <I>modelIndex</I>.  
  159.      *  The <I>modelIndex</I> is the index of the column in the model which
  160.      *  will supply the data for this column in the table. This, like the
  161.      *  <I>columnIdentifier</I> in previous releases, does not change as the
  162.      *  columns are moved in the view.
  163.      *  <p>
  164.      *
  165.      * @param    modelIndex    the column in the model which provides the values for this column
  166.      * @see #setHeaderValue()
  167.      */
  168.     public TableColumn(int modelIndex) {
  169.     this(modelIndex, 75, null, null);
  170.     }
  171.  
  172.     public TableColumn(int modelIndex, int width) {
  173.     this(modelIndex, width, null, null);
  174.     }
  175.  
  176.     public TableColumn(int modelIndex, int width,
  177.                  TableCellRenderer cellRenderer,
  178.                  TableCellEditor cellEditor) {
  179.     super();
  180.     this.modelIndex = modelIndex;
  181.     this.width = width;
  182.     this.cellRenderer = cellRenderer; 
  183.     this.cellEditor = cellEditor; 
  184.     
  185.     // Set other instance variables to default values. 
  186.     minWidth = 15;
  187.     maxWidth = Integer.MAX_VALUE;
  188.     isResizable = true;
  189.     resizedPostingDisableCount = 0;
  190.     setHeaderRenderer(createDefaultHeaderRenderer());
  191.     headerValue = null;
  192.     }
  193.  
  194. //
  195. // Modifying and Querying attributes
  196. //
  197.  
  198.     /**
  199.      * Sets the model index for this column. The model index is the 
  200.      * index of the column in the model that will be displayed by this 
  201.      * TableColumn. As the TableColumn is moved around in the view 
  202.      * the model index remains constant. 
  203.      */
  204.     public void setModelIndex(int anIndex)
  205.     {
  206.     modelIndex = anIndex;
  207.     }
  208.  
  209.     /**
  210.      * Gets the model index for this column. 
  211.      */
  212.     public int getModelIndex()
  213.     {
  214.     return modelIndex;
  215.     }
  216.  
  217.     /**
  218.      * Sets the <B>TableColumn</B>'s identifier to <I>anIdentifier</I>. 
  219.      * Note identifiers are not used by the JTable, they are purely a 
  220.      * convenience for the external tagging and location of columns. 
  221.      *
  222.      * @param       anIdentifier        an identifier for this column
  223.      * @see       #getIdentifier()
  224.      */
  225.     public void setIdentifier(Object anIdentifier)
  226.     {
  227.     identifier = anIdentifier;
  228.     }
  229.  
  230.  
  231.     /**
  232.      *  Returns the identifier object for this column. Note identifiers are not 
  233.      *  used by the JTable, they are purely a convenience for external use. 
  234.      *  If the identifier is <I>null</I> <I>getIdentifier()</I> returns  
  235.      *  <code>getHeaderValue()</code> as a default.
  236.      * 
  237.      * @return    the idenitifer object for this column
  238.      * @see    #setIdentifier()
  239.      */
  240.     public Object getIdentifier()
  241.     {
  242.         return (identifier != null) ? identifier : getHeaderValue();
  243.     
  244.     }
  245.  
  246.     /**
  247.      * Sets the <B>TableCellRenderer</B> used to draw the <B>TableColumn's</B>
  248.      * header to <I>aRenderer</I>.  Posts a bound property change notification
  249.      * with the name HEADER_RENDERER_PROPERTY.
  250.      *
  251.      * @exception IllegalArgumentException    if <I>aRenderer</I> is null.
  252.      * @param      aRenderer            the new header renderer
  253.      * @see      #getHeaderRenderer()
  254.      */
  255.     public void setHeaderRenderer(TableCellRenderer aRenderer)
  256.     {
  257.     TableCellRenderer oldRenderer = headerRenderer;
  258.     
  259.     if (aRenderer == null) {
  260.         throw new IllegalArgumentException("Object is null");
  261.     }
  262.     headerRenderer = aRenderer;
  263.  
  264.     // Post header renderer changed event notification
  265.     if (changeSupport != null) {
  266.         changeSupport.firePropertyChange(HEADER_RENDERER_PROPERTY,
  267.                          oldRenderer, headerRenderer);
  268.     }
  269.     }
  270.  
  271.     /**
  272.      * Returns the <B>TableCellRenderer</B> used to draw the header of the
  273.      * <B>TableColumn</B>. The default header renderer is a
  274.      * <B>JCellRenderer</B> initialized with a <B>JLabel</B>.
  275.      *
  276.      * @return    the <B>TableCellRenderer</B> used to draw the header
  277.      * @see    #setHeaderRenderer()
  278.      * @see    #setHeaderValue()
  279.      */
  280.     public TableCellRenderer getHeaderRenderer()
  281.     {
  282.     return headerRenderer;
  283.     }
  284.  
  285.     /**
  286.      * Sets the <B>Object</B> used as the value for the headerRenderer
  287.      * Posts a bound property change notification with the name
  288.      * HEADER_VALUE_PROPERTY.  
  289.      *
  290.      * @param      aValue            the new header value
  291.      * @see      #getHeaderValue()
  292.      */
  293.     public void setHeaderValue(Object aValue)
  294.     {
  295.     Object oldValue = headerValue;
  296.     
  297.     headerValue = aValue;
  298.  
  299.     // Post header value changed event notification
  300.     if (changeSupport != null) {
  301.         changeSupport.firePropertyChange(HEADER_VALUE_PROPERTY,
  302.                          oldValue, headerValue);
  303.     }
  304.     }
  305.  
  306.     /**
  307.      * Returns the <B>Object</B> used as the value for the header renderer.
  308.      *
  309.      * @return    the <B>Object</B> used as the value for the header renderer
  310.      * @see    #setHeaderValue()
  311.      */
  312.     public Object getHeaderValue() {
  313.     return headerValue;
  314.     }
  315.  
  316.     /**
  317.      * Sets the <B>TableCellRenderer</B> used by <B>JTable</B> to draw
  318.      * individual values for this column to <I>aRenderer</I>.  Posts a
  319.      * bound property change notification with the name CELL_RENDERER_PROPERTY.
  320.      *
  321.      * @param    aRenderer            the new data cell renderer
  322.      * @see    #getCellRenderer()
  323.      */
  324.     public void setCellRenderer(TableCellRenderer aRenderer)
  325.     {
  326.     TableCellRenderer oldRenderer = cellRenderer;
  327.  
  328.     cellRenderer = aRenderer;
  329.  
  330.     // Post cell renderer changed event notification
  331.     if (changeSupport != null) {
  332.         changeSupport.firePropertyChange(CELL_RENDERER_PROPERTY,
  333.                          oldRenderer, cellRenderer);
  334.     }
  335.     }
  336.  
  337.     /**
  338.      * Returns the <B>TableCellRenderer</B> used by the <B>JTable</B> to draw 
  339.      * values for this column.  The <I>cellRenderer</I> of the column not
  340.      * only controls the visual look for the column, but is also used to
  341.      * interpret the value object supplied by the TableModel.  The
  342.      * default <I>cellRenderer</I> is a <B>JCellRenderer</B>
  343.      * initialized with a <B>JLabel</B>.
  344.      *
  345.      * @return    the <B>TableCellRenderer</B> used by the <B>JTable</B> to 
  346.      *         draw values for this column
  347.      * @see    #setCellRenderer()
  348.      */
  349.     public TableCellRenderer getCellRenderer()
  350.     {
  351.     return cellRenderer;
  352.     }
  353.  
  354.     /**
  355.      * Sets the <B>TableCellEditor</B> used by <B>JTable</B> to draw individual 
  356.      * values for this column to <I>anEditor</I>.  A <B>null</B> editor
  357.      * means the column is not editable.
  358.      *
  359.      * @param    anEditor            the new data cell editor
  360.      * @see    #getCellEditor()
  361.      */
  362.     public void setCellEditor(TableCellEditor anEditor)
  363.     {
  364.     cellEditor = anEditor;
  365.     }
  366.  
  367.     /**
  368.      * Returns the <B>TableCellEditor</B> used by the <B>JTable</B> to draw 
  369.      * values for this column.  The <I>cellEditor</I> of the column not
  370.      * only controls the visual look for the column, but is also used to
  371.      * interpret the value object supplied by the TableModel.  The
  372.      * default <I>cellEditor</I> is null.
  373.      *
  374.      * @return    the <B>TableCellEditor</B> used by the <B>JTable</B> to 
  375.      *         draw values for this column
  376.      * @see    #setCellEditor()
  377.      */
  378.     public TableCellEditor getCellEditor()
  379.     {
  380.     return cellEditor;
  381.     }
  382.  
  383.     /**
  384.      * Sets this column's width to <I>newWidth</I>.  If <I>newWidth</I>
  385.      * exceeds the minimum or maximum width, it's adjusted to the
  386.      * appropriate limiting value.    Posts a bound property
  387.      * change notification with the name COLUMN_WIDTH_PROPERTY.
  388.      *
  389.      * @param    newWidth        The new width value
  390.      * @see    #getWidth()
  391.      * @see    #getMinWidth()
  392.      * @see    #setMinWidth()
  393.      * @see    #getMaxWidth()
  394.      * @see    #setMaxWidth()
  395.      */
  396.     public void setWidth(int newWidth)
  397.     {
  398.     int oldWidth = width;
  399.     
  400.     // Do a quick check
  401.     if (width == newWidth)
  402.         return;
  403.  
  404.     // Set the width, and check min & max
  405.     width = newWidth;
  406.     if (width < minWidth)
  407.         width = minWidth;
  408.     else if (width > maxWidth)
  409.         width = maxWidth;
  410.  
  411.     // Post resize event notification
  412.     if (changeSupport != null) {
  413.         changeSupport.firePropertyChange(COLUMN_WIDTH_PROPERTY,
  414.                        new Integer(oldWidth), new Integer(width));
  415.     }
  416.     }
  417.  
  418.     /**
  419.      * Returns the width of the <B>TableColumn</B>. The default width is 
  420.      * 75.
  421.      *
  422.      * @return    the width of the <B>TableColumn</B>
  423.      * @see    #setWidth()
  424.      * @see    #getMinWidth()
  425.      * @see    #setMinWidth()
  426.      * @see    #getMaxWidth()
  427.      * @see    #setMaxWidth()
  428.      */
  429.     public int getWidth()
  430.     {
  431.     return width;
  432.     }
  433.  
  434.     /**
  435.      * Sets the <B>TableColumn's</B> minimum width to <I>newMinWidth</I>,
  436.      * also adjusting the current width if it's less than this value.
  437.      *
  438.      * @param    newMinWidth        the new minimum width value
  439.      * @see    #getWidth()
  440.      * @see    #setWidth()
  441.      * @see    #getMinWidth()
  442.      * @see    #getMaxWidth()
  443.      * @see    #setMaxWidth()
  444.      */
  445.     public void setMinWidth(int newMinWidth)
  446.     {
  447.     minWidth = newMinWidth;
  448.     if (minWidth < 0)
  449.         minWidth = 0;
  450.  
  451.     if (width < minWidth)
  452.         this.setWidth(minWidth);
  453.     }
  454.  
  455.     /**
  456.      * Returns the minimum width for the <B>TableColumn</B>. The 
  457.      * <B>TableColumn's</B> width can't be made less than this either
  458.      * by the user or programmatically.  The default minWidth is 15.
  459.      * 
  460.      * @return    the minimum width for the <B>TableColumn</B>
  461.      * @see    #getWidth()
  462.      * @see    #setWidth()
  463.      * @see    #setMinWidth()
  464.      * @see    #getMaxWidth()
  465.      * @see    #setMaxWidth()
  466.      */
  467.     public int getMinWidth()
  468.     {
  469.     return minWidth;
  470.     }
  471.  
  472.     /**
  473.      * Sets the <B>TableColumn's</B> maximum width to <I>newMaxWidth</I>,
  474.      * also adjusting the current width if it's greater than this value.
  475.      *
  476.      * @param    newMaxWidth        the new maximum width value
  477.      * @see    #getWidth()
  478.      * @see    #setWidth()
  479.      * @see    #getMinWidth()
  480.      * @see    #setMinWidth()
  481.      * @see    #getMaxWidth()
  482.      */
  483.     public void setMaxWidth(int newMaxWidth)
  484.     {
  485.     maxWidth = newMaxWidth;
  486.     if (maxWidth < 0)
  487.         maxWidth = 0;
  488.     else if (maxWidth < minWidth)
  489.         maxWidth = minWidth;
  490.  
  491.     if (width > maxWidth)
  492.         this.setWidth(maxWidth);
  493.     }
  494.  
  495.     /**
  496.      * Returns the maximum width for the <B>TableColumn</B>. The 
  497.      * <B>TableColumn's</B> width can't be made larger than this
  498.      * either by the user or programmatically.  The default maxWidth
  499.      * is 2000.
  500.      *
  501.      * @return    the maximum width for the <B>TableColumn</B>. 
  502.      * @see    #getWidth()
  503.      * @see    #setWidth()
  504.      * @see    #getMinWidth()
  505.      * @see    #setMinWidth()
  506.      * @see    #setMaxWidth()
  507.      */
  508.     public int getMaxWidth()
  509.     {
  510.     return maxWidth;
  511.     }
  512.  
  513.     /**
  514.      * Sets whether the user can resize the receiver in its
  515.      * <B>JTableView</B>.
  516.      *
  517.      * @param    flag        true if the column isResizable
  518.      * @see    #getResizable()
  519.      */
  520.     public void setResizable(boolean flag)
  521.     {
  522.     isResizable = flag;
  523.     }
  524.  
  525.     /**
  526.      * Returns true if the user is allowed to resize the <B>TableColumn</B> 
  527.      * width, false otherwise. You can change the width programmatically
  528.      * regardless of this setting.  The default is true.
  529.      *
  530.      * @return    true if the user is allowed to resize the <B>TableColumn</B> 
  531.      *         width, false otherwise.
  532.      * @see    #setResizable()
  533.      */
  534.     public boolean getResizable()
  535.     {
  536.     return isResizable;
  537.     }
  538.  
  539.     /**
  540.      * Resizes the <B>TableColumn</B> to fit the width of its header cell.
  541.      * If the maximum width is less than the width of the header, the
  542.      * maximum is increased to the header's width. Similarly, if the
  543.      * minimum width is greater than the width of the header, the minimum
  544.      * is reduced to the header's width.
  545.      *
  546.      * @see    #setWidth()
  547.      * @see    #setMinWidth()
  548.      * @see    #setMaxWidth()
  549.      */
  550.     public void sizeWidthToFit() {
  551.     // Get the preferred width of the header
  552.         Component comp;
  553.     comp = this.getHeaderRenderer().getTableCellRendererComponent(null,
  554.                 getHeaderValue(), false, false, 0, 0);
  555.     int headerWidth = comp.getPreferredSize().width;
  556.  
  557.     // Have to adjust the max or min before setting the width
  558.     if (headerWidth > this.getMaxWidth())
  559.         this.setMaxWidth(headerWidth);
  560.     if (headerWidth < this.getMinWidth())
  561.         this.setMinWidth(headerWidth);
  562.  
  563.     // Set the width
  564.     this.setWidth(headerWidth);
  565.     }
  566.  
  567.     public void disableResizedPosting() {
  568.     resizedPostingDisableCount++;
  569.     }
  570.  
  571.     public void enableResizedPosting() {
  572.     resizedPostingDisableCount--;
  573.     }
  574.  
  575. //
  576. // Property Change Support
  577. //
  578.  
  579.     /**
  580.      * Add a PropertyChangeListener to the listener list.
  581.      * The listener is registered for all properties.
  582.      * <p>
  583.      * A PropertyChangeEvent will get fired in response to an
  584.      * explicit setFont, setBackground, or SetForeground on the
  585.      * current component.  Note that if the current component is
  586.      * inheriting its foreground, background, or font from its
  587.      * container, then no event will be fired in response to a
  588.      * change in the inherited property.
  589.      *
  590.      * @param listener  The PropertyChangeListener to be added
  591.      */
  592.  
  593.     public synchronized void addPropertyChangeListener(
  594.                                 PropertyChangeListener listener) {
  595.         if (changeSupport == null) {
  596.             changeSupport = new java.beans.PropertyChangeSupport(this);
  597.         }
  598.         changeSupport.addPropertyChangeListener(listener);
  599.     }
  600.  
  601.     /**
  602.      * Remove a PropertyChangeListener from the listener list.
  603.      * This removes a PropertyChangeListener that was registered
  604.      * for all properties.
  605.      *
  606.      * @param listener  The PropertyChangeListener to be removed
  607.      */
  608.  
  609.     public synchronized void removePropertyChangeListener(
  610.                                 PropertyChangeListener listener) {
  611.         if (changeSupport != null) {
  612.         changeSupport.removePropertyChangeListener(listener);
  613.     }
  614.     }
  615.  
  616. //
  617. // Protected Methods
  618. //
  619.  
  620.     protected TableCellRenderer createDefaultHeaderRenderer() {
  621.     DefaultTableCellRenderer label = new DefaultTableCellRenderer() {
  622.         public Component getTableCellRendererComponent(JTable table, Object value,
  623.                          boolean isSelected, boolean hasFocus, int row, int column) {
  624.             JTableHeader header = table.getTableHeader(); 
  625.             if (isSelected) {
  626.                 setBackground(table.getSelectionBackground());
  627.                 setForeground(table.getSelectionForeground());
  628.                 }
  629.             else {
  630.                 setBackground(header.getBackground());
  631.                 setForeground(header.getForeground());
  632.             }
  633.     
  634.             setFont(header.getFont());
  635.                 setText((value == null) ? "" : value.toString()); 
  636.         
  637.             return this;
  638.             }
  639.     };
  640.     label.setHorizontalAlignment(JLabel.CENTER);
  641.     label.setBorder(BorderFactory.createRaisedBevelBorder());
  642.  
  643.     return label;
  644.     }
  645.  
  646. } // End of class TableColumn
  647.