Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.swing;
   27   
   28   import java.awt.Component;
   29   import java.awt.event;
   30   import java.beans.ConstructorProperties;
   31   import java.lang.Boolean;
   32   import javax.swing.table;
   33   import javax.swing.event;
   34   import java.util.EventObject;
   35   import javax.swing.tree;
   36   import java.io.Serializable;
   37   
   38   /**
   39    * The default editor for table and tree cells.
   40    * <p>
   41    * <strong>Warning:</strong>
   42    * Serialized objects of this class will not be compatible with
   43    * future Swing releases. The current serialization support is
   44    * appropriate for short term storage or RMI between applications running
   45    * the same version of Swing.  As of 1.4, support for long term storage
   46    * of all JavaBeans<sup><font size="-2">TM</font></sup>
   47    * has been added to the <code>java.beans</code> package.
   48    * Please see {@link java.beans.XMLEncoder}.
   49    *
   50    * @author Alan Chung
   51    * @author Philip Milne
   52    */
   53   
   54   public class DefaultCellEditor extends AbstractCellEditor
   55       implements TableCellEditor, TreeCellEditor {
   56   
   57   //
   58   //  Instance Variables
   59   //
   60   
   61       /** The Swing component being edited. */
   62       protected JComponent editorComponent;
   63       /**
   64        * The delegate class which handles all methods sent from the
   65        * <code>CellEditor</code>.
   66        */
   67       protected EditorDelegate delegate;
   68       /**
   69        * An integer specifying the number of clicks needed to start editing.
   70        * Even if <code>clickCountToStart</code> is defined as zero, it
   71        * will not initiate until a click occurs.
   72        */
   73       protected int clickCountToStart = 1;
   74   
   75   //
   76   //  Constructors
   77   //
   78   
   79       /**
   80        * Constructs a <code>DefaultCellEditor</code> that uses a text field.
   81        *
   82        * @param textField  a <code>JTextField</code> object
   83        */
   84       @ConstructorProperties({"component"})
   85       public DefaultCellEditor(final JTextField textField) {
   86           editorComponent = textField;
   87           this.clickCountToStart = 2;
   88           delegate = new EditorDelegate() {
   89               public void setValue(Object value) {
   90                   textField.setText((value != null) ? value.toString() : "");
   91               }
   92   
   93               public Object getCellEditorValue() {
   94                   return textField.getText();
   95               }
   96           };
   97           textField.addActionListener(delegate);
   98       }
   99   
  100       /**
  101        * Constructs a <code>DefaultCellEditor</code> object that uses a check box.
  102        *
  103        * @param checkBox  a <code>JCheckBox</code> object
  104        */
  105       public DefaultCellEditor(final JCheckBox checkBox) {
  106           editorComponent = checkBox;
  107           delegate = new EditorDelegate() {
  108               public void setValue(Object value) {
  109                   boolean selected = false;
  110                   if (value instanceof Boolean) {
  111                       selected = ((Boolean)value).booleanValue();
  112                   }
  113                   else if (value instanceof String) {
  114                       selected = value.equals("true");
  115                   }
  116                   checkBox.setSelected(selected);
  117               }
  118   
  119               public Object getCellEditorValue() {
  120                   return Boolean.valueOf(checkBox.isSelected());
  121               }
  122           };
  123           checkBox.addActionListener(delegate);
  124           checkBox.setRequestFocusEnabled(false);
  125       }
  126   
  127       /**
  128        * Constructs a <code>DefaultCellEditor</code> object that uses a
  129        * combo box.
  130        *
  131        * @param comboBox  a <code>JComboBox</code> object
  132        */
  133       public DefaultCellEditor(final JComboBox comboBox) {
  134           editorComponent = comboBox;
  135           comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
  136           delegate = new EditorDelegate() {
  137               public void setValue(Object value) {
  138                   comboBox.setSelectedItem(value);
  139               }
  140   
  141               public Object getCellEditorValue() {
  142                   return comboBox.getSelectedItem();
  143               }
  144   
  145               public boolean shouldSelectCell(EventObject anEvent) {
  146                   if (anEvent instanceof MouseEvent) {
  147                       MouseEvent e = (MouseEvent)anEvent;
  148                       return e.getID() != MouseEvent.MOUSE_DRAGGED;
  149                   }
  150                   return true;
  151               }
  152               public boolean stopCellEditing() {
  153                   if (comboBox.isEditable()) {
  154                       // Commit edited value.
  155                       comboBox.actionPerformed(new ActionEvent(
  156                                        DefaultCellEditor.this, 0, ""));
  157                   }
  158                   return super.stopCellEditing();
  159               }
  160           };
  161           comboBox.addActionListener(delegate);
  162       }
  163   
  164       /**
  165        * Returns a reference to the editor component.
  166        *
  167        * @return the editor <code>Component</code>
  168        */
  169       public Component getComponent() {
  170           return editorComponent;
  171       }
  172   
  173   //
  174   //  Modifying
  175   //
  176   
  177       /**
  178        * Specifies the number of clicks needed to start editing.
  179        *
  180        * @param count  an int specifying the number of clicks needed to start editing
  181        * @see #getClickCountToStart
  182        */
  183       public void setClickCountToStart(int count) {
  184           clickCountToStart = count;
  185       }
  186   
  187       /**
  188        * Returns the number of clicks needed to start editing.
  189        * @return the number of clicks needed to start editing
  190        */
  191       public int getClickCountToStart() {
  192           return clickCountToStart;
  193       }
  194   
  195   //
  196   //  Override the implementations of the superclass, forwarding all methods
  197   //  from the CellEditor interface to our delegate.
  198   //
  199   
  200       /**
  201        * Forwards the message from the <code>CellEditor</code> to
  202        * the <code>delegate</code>.
  203        * @see EditorDelegate#getCellEditorValue
  204        */
  205       public Object getCellEditorValue() {
  206           return delegate.getCellEditorValue();
  207       }
  208   
  209       /**
  210        * Forwards the message from the <code>CellEditor</code> to
  211        * the <code>delegate</code>.
  212        * @see EditorDelegate#isCellEditable(EventObject)
  213        */
  214       public boolean isCellEditable(EventObject anEvent) {
  215           return delegate.isCellEditable(anEvent);
  216       }
  217   
  218       /**
  219        * Forwards the message from the <code>CellEditor</code> to
  220        * the <code>delegate</code>.
  221        * @see EditorDelegate#shouldSelectCell(EventObject)
  222        */
  223       public boolean shouldSelectCell(EventObject anEvent) {
  224           return delegate.shouldSelectCell(anEvent);
  225       }
  226   
  227       /**
  228        * Forwards the message from the <code>CellEditor</code> to
  229        * the <code>delegate</code>.
  230        * @see EditorDelegate#stopCellEditing
  231        */
  232       public boolean stopCellEditing() {
  233           return delegate.stopCellEditing();
  234       }
  235   
  236       /**
  237        * Forwards the message from the <code>CellEditor</code> to
  238        * the <code>delegate</code>.
  239        * @see EditorDelegate#cancelCellEditing
  240        */
  241       public void cancelCellEditing() {
  242           delegate.cancelCellEditing();
  243       }
  244   
  245   //
  246   //  Implementing the TreeCellEditor Interface
  247   //
  248   
  249       /** Implements the <code>TreeCellEditor</code> interface. */
  250       public Component getTreeCellEditorComponent(JTree tree, Object value,
  251                                                   boolean isSelected,
  252                                                   boolean expanded,
  253                                                   boolean leaf, int row) {
  254           String         stringValue = tree.convertValueToText(value, isSelected,
  255                                               expanded, leaf, row, false);
  256   
  257           delegate.setValue(stringValue);
  258           return editorComponent;
  259       }
  260   
  261   //
  262   //  Implementing the CellEditor Interface
  263   //
  264       /** Implements the <code>TableCellEditor</code> interface. */
  265       public Component getTableCellEditorComponent(JTable table, Object value,
  266                                                    boolean isSelected,
  267                                                    int row, int column) {
  268           delegate.setValue(value);
  269           if (editorComponent instanceof JCheckBox) {
  270               //in order to avoid a "flashing" effect when clicking a checkbox
  271               //in a table, it is important for the editor to have as a border
  272               //the same border that the renderer has, and have as the background
  273               //the same color as the renderer has. This is primarily only
  274               //needed for JCheckBox since this editor doesn't fill all the
  275               //visual space of the table cell, unlike a text field.
  276               TableCellRenderer renderer = table.getCellRenderer(row, column);
  277               Component c = renderer.getTableCellRendererComponent(table, value,
  278                       isSelected, true, row, column);
  279               if (c != null) {
  280                   editorComponent.setOpaque(true);
  281                   editorComponent.setBackground(c.getBackground());
  282                   if (c instanceof JComponent) {
  283                       editorComponent.setBorder(((JComponent)c).getBorder());
  284                   }
  285               } else {
  286                   editorComponent.setOpaque(false);
  287               }
  288           }
  289           return editorComponent;
  290       }
  291   
  292   
  293   //
  294   //  Protected EditorDelegate class
  295   //
  296   
  297       /**
  298        * The protected <code>EditorDelegate</code> class.
  299        */
  300       protected class EditorDelegate implements ActionListener, ItemListener, Serializable {
  301   
  302           /**  The value of this cell. */
  303           protected Object value;
  304   
  305          /**
  306           * Returns the value of this cell.
  307           * @return the value of this cell
  308           */
  309           public Object getCellEditorValue() {
  310               return value;
  311           }
  312   
  313          /**
  314           * Sets the value of this cell.
  315           * @param value the new value of this cell
  316           */
  317           public void setValue(Object value) {
  318               this.value = value;
  319           }
  320   
  321          /**
  322           * Returns true if <code>anEvent</code> is <b>not</b> a
  323           * <code>MouseEvent</code>.  Otherwise, it returns true
  324           * if the necessary number of clicks have occurred, and
  325           * returns false otherwise.
  326           *
  327           * @param   anEvent         the event
  328           * @return  true  if cell is ready for editing, false otherwise
  329           * @see #setClickCountToStart
  330           * @see #shouldSelectCell
  331           */
  332           public boolean isCellEditable(EventObject anEvent) {
  333               if (anEvent instanceof MouseEvent) {
  334                   return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
  335               }
  336               return true;
  337           }
  338   
  339          /**
  340           * Returns true to indicate that the editing cell may
  341           * be selected.
  342           *
  343           * @param   anEvent         the event
  344           * @return  true
  345           * @see #isCellEditable
  346           */
  347           public boolean shouldSelectCell(EventObject anEvent) {
  348               return true;
  349           }
  350   
  351          /**
  352           * Returns true to indicate that editing has begun.
  353           *
  354           * @param anEvent          the event
  355           */
  356           public boolean startCellEditing(EventObject anEvent) {
  357               return true;
  358           }
  359   
  360          /**
  361           * Stops editing and
  362           * returns true to indicate that editing has stopped.
  363           * This method calls <code>fireEditingStopped</code>.
  364           *
  365           * @return  true
  366           */
  367           public boolean stopCellEditing() {
  368               fireEditingStopped();
  369               return true;
  370           }
  371   
  372          /**
  373           * Cancels editing.  This method calls <code>fireEditingCanceled</code>.
  374           */
  375          public void cancelCellEditing() {
  376              fireEditingCanceled();
  377          }
  378   
  379          /**
  380           * When an action is performed, editing is ended.
  381           * @param e the action event
  382           * @see #stopCellEditing
  383           */
  384           public void actionPerformed(ActionEvent e) {
  385               DefaultCellEditor.this.stopCellEditing();
  386           }
  387   
  388          /**
  389           * When an item's state changes, editing is ended.
  390           * @param e the action event
  391           * @see #stopCellEditing
  392           */
  393           public void itemStateChanged(ItemEvent e) {
  394               DefaultCellEditor.this.stopCellEditing();
  395           }
  396       }
  397   
  398   } // End of class JCellEditor

Home » openjdk-7 » javax » swing » [javadoc | source]