TableColumnExt.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:13k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: TableColumnExt.java,v 1.5 2005/10/10 18:03:02 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx.table;
  22. import java.beans.PropertyChangeEvent;
  23. import java.beans.PropertyChangeListener;
  24. import java.lang.reflect.Constructor;
  25. import java.util.Comparator;
  26. import java.util.Hashtable;
  27. import javax.swing.table.TableCellEditor;
  28. import javax.swing.table.TableCellRenderer;
  29. import org.jdesktop.swingx.decorator.Sorter;
  30. /**
  31.  * TableColumn extension which adds support for view column configuration features
  32.  * including column-visibility, sorting, and prototype values.
  33.  *
  34.  * @author Ramesh Gupta
  35.  * @author Amy Fowler
  36.  */
  37. public class TableColumnExt extends javax.swing.table.TableColumn
  38.     implements Cloneable {
  39.     public static final String SORTER_COMPARATOR = "Sorter.COMPARATOR";
  40.     protected boolean editable = true;
  41.     protected boolean visible = true;
  42.     protected Object prototypeValue = null;
  43.     private Hashtable clientProperties = null;
  44.     protected Sorter sorter = null;
  45.     private Constructor sorterConstructor = null;
  46.     private final static Constructor defaultSorterConstructor;
  47.     private final static Class[] sorterConstructorSignature =
  48.         new Class[]{int.class, boolean.class};
  49.     static {
  50.         Constructor constructor = null;
  51.         try {
  52.             Class sorterClass = Class.forName("org.jdesktop.swingx.decorator.ShuttleSorter", true,
  53.                                               TableColumnExt.class.getClassLoader());
  54.             constructor = sorterClass.getConstructor(sorterConstructorSignature);
  55.         }
  56.         catch (Exception ex) {
  57.         }
  58.         defaultSorterConstructor = constructor;
  59.     }
  60.     /**
  61.      * Creates new table view column with a model index = 0.
  62.      */
  63.     public TableColumnExt() {
  64.         this(0);
  65.     }
  66.     /**
  67.      * Creates new table view column with the specified model index.
  68.      * @param modelIndex index of table model column to which this view column
  69.      *        is bound.
  70.      */
  71.     public TableColumnExt(int modelIndex) {
  72.         this(modelIndex, 75); // default width taken from javax.swing.table.TableColumn
  73.     }
  74.     /**
  75.      * Creates new table view column with the specified model index and column width.
  76.      * @param modelIndex index of table model column to which this view column
  77.      *        is bound.
  78.      * @param width pixel width of view column
  79.      */
  80.     public TableColumnExt(int modelIndex, int width) {
  81.         this(modelIndex, width, null, null);
  82.     }
  83.     /**
  84.      * Creates new table view column with the specified model index, column
  85.      * width, cell renderer and cell editor.
  86.      * @param modelIndex index of table model column to which this view column
  87.      *        is bound.
  88.      * @param width pixel width of view column
  89.      * @param cellRenderer the cell renderer which will render all cells in this
  90.      *        view column
  91.      * @param cellEditor the cell editor which will edit cells in this view column
  92.      */
  93.     public TableColumnExt(int modelIndex, int width,
  94.                           TableCellRenderer cellRenderer, TableCellEditor cellEditor) {
  95.         super(modelIndex, width, cellRenderer, cellEditor);
  96.         this.sorterConstructor = defaultSorterConstructor;
  97.     }
  98.     /** cosmetic override: don't fool users if resize is
  99.      * not possible due to fixed column width.
  100.      */
  101.     public boolean getResizable() {
  102.         return super.getResizable() && (getMinWidth() < getMaxWidth());
  103.     }
  104.     /**
  105.      * Sets the editable property.  This property enables the table view to
  106.      * control whether or not the user is permitted to edit cell values in this
  107.      * view column, even if the model permits.  If the table model column corresponding to this view column
  108.      * returns <code>true</code> for <code>isCellEditable</code> and this
  109.      * property is <code>false</code>, then the user will not be permitted to
  110.      * edit values from this view column, dispite the model setting.
  111.      * If the model's <code>isCellEditable</code> returns <code>false</code>,
  112.      * then this property will be ignored and cell edits will not be permitted
  113.      * in this view column.
  114.      * @see #isEditable
  115.      * @see javax.swing.table.TableModel#isCellEditable
  116.      * @param editable boolean indicating whether or not the user may edit cell
  117.      *        values in this view column
  118.      */
  119.     public void setEditable(boolean editable) {
  120.         boolean oldEditable = this.editable;
  121.         this.editable = editable;
  122.         firePropertyChange("editable",
  123.                            Boolean.valueOf(oldEditable),
  124.                            Boolean.valueOf(editable));
  125.     }
  126.     /**
  127.      * @see #setEditable
  128.      * @return boolean indicating whether or not the user may edit cell
  129.      *        values in this view column
  130.      */
  131.     public boolean isEditable() {
  132.         return editable;
  133.     }
  134.     /**
  135.      * Sets the prototypeValue property.  The value should be of a type
  136.      * which corresponds to the column's class as defined by the table model.
  137.      * If non-null, the JXTable instance will use this property to calculate
  138.      * and set the initial preferredWidth of the column.  Note that this
  139.      * initial preferredWidth will be overridden if the user resizes columns
  140.      * directly.
  141.      * @see #getPrototypeValue
  142.      * @see org.jdesktop.swingx.JXTable#getPreferredScrollableViewportSize
  143.      * @param value Object containing the value of the prototype to be used
  144.      *         to calculate the initial preferred width of the column
  145.      */
  146.     public void setPrototypeValue(Object value) {
  147.         Object oldPrototypeValue = this.prototypeValue;
  148.         this.prototypeValue = value;
  149.         firePropertyChange("prototypeValue",
  150.                            oldPrototypeValue,
  151.                            value);
  152.     }
  153.     /**
  154.      * @see #setPrototypeValue
  155.      * @return Object containing the value of the prototype to be used
  156.      *         to calculate the initial preferred width of the column
  157.      */
  158.     public Object getPrototypeValue() {
  159.         return prototypeValue;
  160.     }
  161.     /**
  162.      * Sets a user-defined sorter for this column
  163.      * @param sorterClassName String containing the name of the class which
  164.      *        performs sorting on this view column
  165.      */
  166.     public void setSorterClass(String sorterClassName) {
  167.         if ((sorterClassName == null) || (sorterClassName.length() == 0)){
  168.             sorterConstructor = null;
  169.         }
  170.         else {
  171.             try {
  172.                 Class sorterClass = Class.forName(sorterClassName, true,
  173.                                                   getClass().getClassLoader());
  174.                 sorterConstructor = sorterClass.getConstructor(sorterConstructorSignature);
  175.             }
  176.             catch (Exception ex) {
  177.                 sorterConstructor = null;
  178.             }
  179.         }
  180.     }
  181.     /**
  182.      *
  183.      * @return String containing the name of the class which
  184.      *         performs sorting on this view column
  185.      */
  186.     public String getSorterClass() {
  187.         return sorterConstructor == null ? null :
  188.             sorterConstructor.getDeclaringClass().getName();
  189.     }
  190.     /**
  191.      *
  192.      * @return Sorter instance which performs sorting on this view column
  193.      */
  194.     public Sorter getSorter() {
  195.         if (sorter == null) {
  196.             if (sorterConstructor != null) {
  197.                 try {
  198.                     sorter = (Sorter) sorterConstructor.newInstance(
  199.                         new Object[] {
  200.                             new Integer(getModelIndex()),
  201.                             new Boolean(true)});
  202.                     Object object = getClientProperty(SORTER_COMPARATOR);
  203.                     if (object instanceof Comparator) {
  204.                         sorter.setComparator((Comparator) object);
  205.                     }
  206.                 }
  207.                 catch (Exception ex) {
  208.                 }
  209.             }
  210.         }
  211.         return sorter;
  212.     }
  213.     /**
  214.      *
  215.      * @return boolean indicating whether this view column is sortable
  216.      */
  217.     public boolean isSortable() {
  218.         return sorterConstructor != null;
  219.     }
  220.     /**
  221.      * Sets the title of this view column.  This is a convenience
  222.      * wrapper for <code>setHeaderValue</code>.
  223.      * @param title String containing the title of this view column
  224.      */
  225.     public void setTitle(String title) {
  226.         setHeaderValue(title); // simple wrapper
  227.     }
  228.     /**
  229.      * Convenience method which returns the headerValue property after
  230.      * converting it to a string.
  231.      * @return String containing the title of this view column
  232.      */
  233.     public String getTitle() {
  234.         return getHeaderValue().toString(); // simple wrapper
  235.     }
  236.     /**
  237.      * Sets the visible property.  This property controls whether or not
  238.      * this view column is currently visible in the table.
  239.      * @see #setVisible
  240.      * @param visible boolean indicating whether or not this view column is
  241.      *        visible in the table
  242.      */
  243.     public void setVisible(boolean visible) {
  244.         boolean oldVisible = this.visible;
  245.         this.visible = visible;
  246.         firePropertyChange("visible",
  247.                            Boolean.valueOf(oldVisible),
  248.                            Boolean.valueOf(visible));
  249.     }
  250.     /**
  251.      * @see #setVisible
  252.      * @return boolean indicating whether or not this view column is
  253.      *        visible in the table
  254.      */
  255.     public boolean isVisible() {
  256.         return visible;
  257.     }
  258.     /**
  259.      * Stores the object value using the specified key.
  260.      * @see #getClientProperty
  261.      * @param key Object which is used as key to retrieve value
  262.      * @param value Object containing value of client property
  263.      */
  264.     public void putClientProperty(Object key, Object value) {
  265.         if (key == null)
  266.             throw new IllegalArgumentException("null key");
  267.         if ((value == null) && (getClientProperty(key) == null)) {
  268.             return;
  269.         }
  270.         if (value == null) {
  271.             getClientProperties().remove(key);
  272.         }
  273.         else {
  274.             getClientProperties().put(key, value);
  275.         }
  276.         /** @todo Support firePropertyChange(key.toString(), oldValue, newValue);
  277.          * Make all fireXXX methods in TableColumn protected instead of private */
  278.     }
  279.     /**
  280.      * Retrieves the object value using the specified key.
  281.      * @see #putClientProperty
  282.      * @param key Object which is used as key to retrieve value
  283.      * @return Object containing value of client property
  284.      */
  285.     public Object getClientProperty(Object key) {
  286.         return ((key == null) || (clientProperties == null)) ?
  287.                 null : clientProperties.get(key);
  288.     }
  289.     private Hashtable getClientProperties() {
  290.         if (clientProperties == null) {
  291.             clientProperties = new Hashtable();
  292.         }
  293.         return clientProperties;
  294.     }
  295.     /**
  296.       * Returns a clone of this TableColumn. Some implementations of TableColumn
  297.       * may assume that all TableColumnModels are unique, therefore it is
  298.       * recommended that the same TableColumn instance not be added more than
  299.       * once to a TableColumnModel. To show TableColumns with the same column of
  300.       * data from the model, create a new instance with the same modelIndex.
  301.       *
  302.       * @return a clone of this TableColumn
  303.       */
  304.      public Object clone() {
  305.          // JW: where are the client properties?
  306.          final TableColumnExt copy = new TableColumnExt(
  307.              this.getModelIndex(), this.getWidth(),
  308.              this.getCellRenderer(), this.getCellEditor());
  309.          copy.setEditable(this.isEditable());
  310.          copy.setHeaderValue(this.getHeaderValue()); // no need to copy setTitle();
  311.          copy.setIdentifier(this.getIdentifier());
  312.          copy.setMaxWidth(this.getMaxWidth());
  313.          copy.setMinWidth(this.getMinWidth());
  314.          copy.setPreferredWidth(this.getPreferredWidth());
  315.          copy.setPrototypeValue(this.getPrototypeValue());
  316.          // JW: isResizable is overridden to return a calculated property!
  317.          copy.setResizable(super.getResizable());
  318.          copy.setVisible(this.isVisible());
  319.          copy.setSorterClass(this.getSorterClass());
  320.          copy.sorterConstructor = sorterConstructor;
  321.          return copy;
  322.      }
  323.      protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
  324.          if ((oldValue != null && !oldValue.equals(newValue)) ||
  325.               oldValue == null && newValue != null) {
  326.              PropertyChangeListener pcl[] = getPropertyChangeListeners();
  327.              if (pcl != null && pcl.length != 0) {
  328.                  PropertyChangeEvent pce = new PropertyChangeEvent(this,
  329.                      propertyName,
  330.                      oldValue, newValue);
  331.                  for (int i = 0; i < pcl.length; i++) {
  332.                      pcl[i].propertyChange(pce);
  333.                  }
  334.              }
  335.          }
  336.      }
  337. }