    rev 48858 : Work in progress for JDK-6303622
    Use generic in Swing components like JComboBox
    1. Added generic return type and parameter type for JComboBox.
    2. Modified JList related classes as well.
    3. Reverted the changes made to "getSelectedValues" as suggested by Joe.
    4. Modified files that were failing on Linux and Mac as well.

       1 /*
       2  * Copyright (c) 1997, 2014, 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&trade;
      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  * @since 1.2
      53  */
      54 @SuppressWarnings("serial") // Same-version serialization only
      55 public class DefaultCellEditor extends AbstractCellEditor
      56     implements TableCellEditor, TreeCellEditor {
      57
      58 //
      59 //  Instance Variables
      60 //
      61
      62     /** The Swing component being edited. */
      63     protected JComponent editorComponent;
      64     /**
      65      * The delegate class which handles all methods sent from the
      66      * <code>CellEditor</code>.
      67      */
      68     protected EditorDelegate delegate;
      69     /**
      70      * An integer specifying the number of clicks needed to start editing.
      71      * Even if <code>clickCountToStart</code> is defined as zero, it
      72      * will not initiate until a click occurs.
      73      */
      74     protected int clickCountToStart = 1;
      75
      76 //
      77 //  Constructors
      78 //
      79
      80     /**
      81      * Constructs a <code>DefaultCellEditor</code> that uses a text field.
      82      *
      83      * @param textField  a <code>JTextField</code> object
      84      */
      85     @ConstructorProperties({"component"})
      86     public DefaultCellEditor(final JTextField textField) {
      87         editorComponent = textField;
      88         this.clickCountToStart = 2;
      89         delegate = new EditorDelegate() {
      90             public void setValue(Object value) {
      91                 textField.setText((value != null) ? value.toString() : "");
      92             }
      93
      94             public Object getCellEditorValue() {
      95                 return textField.getText();
      96             }
      97         };
      98         textField.addActionListener(delegate);
      99     }
     100
     101     /**
     102      * Constructs a <code>DefaultCellEditor</code> object that uses a check box.
     103      *
     104      * @param checkBox  a <code>JCheckBox</code> object
     105      */
     106     public DefaultCellEditor(final JCheckBox checkBox) {
     107         editorComponent = checkBox;
     108         delegate = new EditorDelegate() {
     109             public void setValue(Object value) {
     110                 boolean selected = false;
     111                 if (value instanceof Boolean) {
     112                     selected = ((Boolean)value).booleanValue();
     113                 }
     114                 else if (value instanceof String) {
     115                     selected = value.equals("true");
     116                 }
     117                 checkBox.setSelected(selected);
     118             }
     119
     120             public Object getCellEditorValue() {
     121                 return Boolean.valueOf(checkBox.isSelected());
     122             }
     123         };
     124         checkBox.addActionListener(delegate);
     125         checkBox.setRequestFocusEnabled(false);
     126     }
     127
     128     /**
     129      * Constructs a <code>DefaultCellEditor</code> object that uses a
     130      * combo box.
     131      *
     132      * @param comboBox  a <code>JComboBox</code> object
     133      */
     134     public DefaultCellEditor(final JComboBox<?> comboBox) {

     135         editorComponent = comboBox;
     136         comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
     137         delegate = new EditorDelegate() {
     138             public void setValue(Object value) {
     139                 comboBox.setSelectedItem(value);
     140             }
     141
     142             public Object getCellEditorValue() {
     143                 return comboBox.getSelectedItem();
     144             }
     145
     146             public boolean shouldSelectCell(EventObject anEvent) {
     147                 if (anEvent instanceof MouseEvent) {
     148                     MouseEvent e = (MouseEvent)anEvent;
     149                     return e.getID() != MouseEvent.MOUSE_DRAGGED;
     150                 }
     151                 return true;
     152             }
     153             public boolean stopCellEditing() {
     154                 if (comboBox.isEditable()) {
     155                     // Commit edited value.
     156                     comboBox.actionPerformed(new ActionEvent(
     157                                      DefaultCellEditor.this, 0, ""));
     158                 }
     159                 return super.stopCellEditing();
     160             }
     161         };
     162         comboBox.addActionListener(delegate);
     163     }
     164
     165     /**
     166      * Returns a reference to the editor component.
     167      *
     168      * @return the editor <code>Component</code>
     169      */
     170     public Component getComponent() {
     171         return editorComponent;
     172     }
     173
     174 //
     175 //  Modifying
     176 //
     177
     178     /**
     179      * Specifies the number of clicks needed to start editing.
     180      *
     181      * @param count  an int specifying the number of clicks needed to start editing
     182      * @see #getClickCountToStart
     183      */
     184     public void setClickCountToStart(int count) {
     185         clickCountToStart = count;
     186     }
     187
     188     /**
     189      * Returns the number of clicks needed to start editing.
     190      * @return the number of clicks needed to start editing
     191      */
     192     public int getClickCountToStart() {
     193         return clickCountToStart;
     194     }
     195
     196 //
     197 //  Override the implementations of the superclass, forwarding all methods
     198 //  from the CellEditor interface to our delegate.
     199 //
     200
     201     /**
     202      * Forwards the message from the <code>CellEditor</code> to
     203      * the <code>delegate</code>.
     204      * @see EditorDelegate#getCellEditorValue
     205      */
     206     public Object getCellEditorValue() {
     207         return delegate.getCellEditorValue();
     208     }
     209
     210     /**
     211      * Forwards the message from the <code>CellEditor</code> to
     212      * the <code>delegate</code>.
     213      * @see EditorDelegate#isCellEditable(EventObject)
     214      */
     215     public boolean isCellEditable(EventObject anEvent) {
     216         return delegate.isCellEditable(anEvent);
     217     }
     218
     219     /**
     220      * Forwards the message from the <code>CellEditor</code> to
     221      * the <code>delegate</code>.
     222      * @see EditorDelegate#shouldSelectCell(EventObject)
     223      */
     224     public boolean shouldSelectCell(EventObject anEvent) {
     225         return delegate.shouldSelectCell(anEvent);
     226     }
     227
     228     /**
     229      * Forwards the message from the <code>CellEditor</code> to
     230      * the <code>delegate</code>.
     231      * @see EditorDelegate#stopCellEditing
     232      */
     233     public boolean stopCellEditing() {
     234         return delegate.stopCellEditing();
     235     }
     236
     237     /**
     238      * Forwards the message from the <code>CellEditor</code> to
     239      * the <code>delegate</code>.
     240      * @see EditorDelegate#cancelCellEditing
     241      */
     242     public void cancelCellEditing() {
     243         delegate.cancelCellEditing();
     244     }
     245
     246 //
     247 //  Implementing the TreeCellEditor Interface
     248 //
     249
     250     /** Implements the <code>TreeCellEditor</code> interface. */
     251     public Component getTreeCellEditorComponent(JTree tree, Object value,
     252                                                 boolean isSelected,
     253                                                 boolean expanded,
     254                                                 boolean leaf, int row) {
     255         String         stringValue = tree.convertValueToText(value, isSelected,
     256                                             expanded, leaf, row, false);
     257
     258         delegate.setValue(stringValue);
     259         return editorComponent;
     260     }
     261
     262 //
     263 //  Implementing the CellEditor Interface
     264 //
     265     /** Implements the <code>TableCellEditor</code> interface. */
     266     public Component getTableCellEditorComponent(JTable table, Object value,
     267                                                  boolean isSelected,
     268                                                  int row, int column) {
     269         delegate.setValue(value);
     270         if (editorComponent instanceof JCheckBox) {
     271             //in order to avoid a "flashing" effect when clicking a checkbox
     272             //in a table, it is important for the editor to have as a border
     273             //the same border that the renderer has, and have as the background
     274             //the same color as the renderer has. This is primarily only
     275             //needed for JCheckBox since this editor doesn't fill all the
     276             //visual space of the table cell, unlike a text field.
     277             TableCellRenderer renderer = table.getCellRenderer(row, column);
     278             Component c = renderer.getTableCellRendererComponent(table, value,
     279                     isSelected, true, row, column);
     280             if (c != null) {
     281                 editorComponent.setOpaque(true);
     282                 editorComponent.setBackground(c.getBackground());
     283                 if (c instanceof JComponent) {
     284                     editorComponent.setBorder(((JComponent)c).getBorder());
     285                 }
     286             } else {
     287                 editorComponent.setOpaque(false);
     288             }
     289         }
     290         return editorComponent;
     291     }
     292
     293
     294 //
     295 //  Protected EditorDelegate class
     296 //
     297
     298     /**
     299      * The protected <code>EditorDelegate</code> class.
     300      */
     301     protected class EditorDelegate implements ActionListener, ItemListener, Serializable {
     302
     303         /**  The value of this cell. */
     304         protected Object value;
     305
     306        /**
     307         * Returns the value of this cell.
     308         * @return the value of this cell
     309         */
     310         public Object getCellEditorValue() {
     311             return value;
     312         }
     313
     314        /**
     315         * Sets the value of this cell.
     316         * @param value the new value of this cell
     317         */
     318         public void setValue(Object value) {
     319             this.value = value;
     320         }
     321
     322        /**
     323         * Returns true if <code>anEvent</code> is <b>not</b> a
     324         * <code>MouseEvent</code>.  Otherwise, it returns true
     325         * if the necessary number of clicks have occurred, and
     326         * returns false otherwise.
     327         *
     328         * @param   anEvent         the event
     329         * @return  true  if cell is ready for editing, false otherwise
     330         * @see #setClickCountToStart
     331         * @see #shouldSelectCell
     332         */
     333         public boolean isCellEditable(EventObject anEvent) {
     334             if (anEvent instanceof MouseEvent) {
     335                 return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
     336             }
     337             return true;
     338         }
     339
     340        /**
     341         * Returns true to indicate that the editing cell may
     342         * be selected.
     343         *
     344         * @param   anEvent         the event
     345         * @return  true
     346         * @see #isCellEditable
     347         */
     348         public boolean shouldSelectCell(EventObject anEvent) {
     349             return true;
     350         }
     351
     352        /**
     353         * Returns true to indicate that editing has begun.
     354         *
     355         * @param anEvent          the event
     356         * @return true to indicate editing has begun
     357         */
     358         public boolean startCellEditing(EventObject anEvent) {
     359             return true;
     360         }
     361
     362        /**
     363         * Stops editing and
     364         * returns true to indicate that editing has stopped.
     365         * This method calls <code>fireEditingStopped</code>.
     366         *
     367         * @return  true
     368         */
     369         public boolean stopCellEditing() {
     370             fireEditingStopped();
     371             return true;
     372         }
     373
     374        /**
     375         * Cancels editing.  This method calls <code>fireEditingCanceled</code>.
     376         */
     377        public void cancelCellEditing() {
     378            fireEditingCanceled();
     379        }
     380
     381        /**
     382         * When an action is performed, editing is ended.
     383         * @param e the action event
     384         * @see #stopCellEditing
     385         */
     386         public void actionPerformed(ActionEvent e) {
     387             DefaultCellEditor.this.stopCellEditing();
     388         }
     389
     390        /**
     391         * When an item's state changes, editing is ended.
     392         * @param e the action event
     393         * @see #stopCellEditing
     394         */
     395         public void itemStateChanged(ItemEvent e) {
     396             DefaultCellEditor.this.stopCellEditing();
     397         }
     398     }
     399
     400 } // End of class JCellEditor
    --- EOF ---