Use Tree Navigation
protected class

DefaultCellEditor.EditorDelegate

extends Object
implements ActionListener ItemListener Serializable
/*
 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


package javax.swing;

import java.awt.Component;
import java.awt.event.*;
import java.lang.Boolean;
import javax.swing.table.*;
import javax.swing.event.*;
import java.util.EventObject;
import javax.swing.tree.*;
import java.io.Serializable;

/**
 * The default editor for table and tree cells.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @author Alan Chung
 * @author Philip Milne
 */


public class DefaultCellEditor extends AbstractCellEditor
   
implements TableCellEditor, TreeCellEditor {

//
//  Instance Variables
//

   
/** The Swing component being edited. */
   
protected JComponent editorComponent;
   
/**
     * The delegate class which handles all methods sent from the
     * <code>CellEditor</code>.
     */

   
protected EditorDelegate delegate;
   
/**
     * An integer specifying the number of clicks needed to start editing.
     * Even if <code>clickCountToStart</code> is defined as zero, it
     * will not initiate until a click occurs.
     */

   
protected int clickCountToStart = 1;

//
//  Constructors
//

   
/**
     * Constructs a <code>DefaultCellEditor</code> that uses a text field.
     *
     * @param textField  a <code>JTextField</code> object
     */

   
public DefaultCellEditor(final JTextField textField) {
        editorComponent
= textField;
       
this.clickCountToStart = 2;
       
delegate = new EditorDelegate() {
           
public void setValue(Object value) {
                textField
.setText((value != null) ? value.toString() : "");
           
}

           
public Object getCellEditorValue() {
               
return textField.getText();
           
}
       
};
        textField
.addActionListener(delegate);
   
}

   
/**
     * Constructs a <code>DefaultCellEditor</code> object that uses a check box.
     *
     * @param checkBox  a <code>JCheckBox</code> object
     */

   
public DefaultCellEditor(final JCheckBox checkBox) {
        editorComponent
= checkBox;
       
delegate = new EditorDelegate() {
           
public void setValue(Object value) {
               
boolean selected = false;
               
if (value instanceof Boolean) {
                    selected
= ((Boolean)value).booleanValue();
               
}
               
else if (value instanceof String) {
                    selected
= value.equals("true");
               
}
                checkBox
.setSelected(selected);
           
}

           
public Object getCellEditorValue() {
               
return Boolean.valueOf(checkBox.isSelected());
           
}
       
};
        checkBox
.addActionListener(delegate);
        checkBox
.setRequestFocusEnabled(false);
   
}

   
/**
     * Constructs a <code>DefaultCellEditor</code> object that uses a
     * combo box.
     *
     * @param comboBox  a <code>JComboBox</code> object
     */

   
public DefaultCellEditor(final JComboBox comboBox) {
        editorComponent
= comboBox;
        comboBox
.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
       
delegate = new EditorDelegate() {
           
public void setValue(Object value) {
                comboBox
.setSelectedItem(value);
           
}

           
public Object getCellEditorValue() {
               
return comboBox.getSelectedItem();
           
}

           
public boolean shouldSelectCell(EventObject anEvent) {
               
if (anEvent instanceof MouseEvent) {
                   
MouseEvent e = (MouseEvent)anEvent;
                   
return e.getID() != MouseEvent.MOUSE_DRAGGED;
               
}
               
return true;
           
}
           
public boolean stopCellEditing() {
               
if (comboBox.isEditable()) {
                   
// Commit edited value.
                    comboBox
.actionPerformed(new ActionEvent(
                                     
DefaultCellEditor.this, 0, ""));
               
}
               
return super.stopCellEditing();
           
}
       
};
        comboBox
.addActionListener(delegate);
   
}

   
/**
     * Returns a reference to the editor component.
     *
     * @return the editor <code>Component</code>
     */

   
public Component getComponent() {
       
return editorComponent;
   
}

//
//  Modifying
//

   
/**
     * Specifies the number of clicks needed to start editing.
     *
     * @param count  an int specifying the number of clicks needed to start editing
     * @see #getClickCountToStart
     */

   
public void setClickCountToStart(int count) {
        clickCountToStart
= count;
   
}

   
/**
     * Returns the number of clicks needed to start editing.
     * @return the number of clicks needed to start editing
     */

   
public int getClickCountToStart() {
       
return clickCountToStart;
   
}

//
//  Override the implementations of the superclass, forwarding all methods
//  from the CellEditor interface to our delegate.
//

   
/**
     * Forwards the message from the <code>CellEditor</code> to
     * the <code>delegate</code>.
     * @see EditorDelegate#getCellEditorValue
     */

   
public Object getCellEditorValue() {
       
return delegate.getCellEditorValue();
   
}

   
/**
     * Forwards the message from the <code>CellEditor</code> to
     * the <code>delegate</code>.
     * @see EditorDelegate#isCellEditable(EventObject)
     */

   
public boolean isCellEditable(EventObject anEvent) {
       
return delegate.isCellEditable(anEvent);
   
}

   
/**
     * Forwards the message from the <code>CellEditor</code> to
     * the <code>delegate</code>.
     * @see EditorDelegate#shouldSelectCell(EventObject)
     */

   
public boolean shouldSelectCell(EventObject anEvent) {
       
return delegate.shouldSelectCell(anEvent);
   
}

   
/**
     * Forwards the message from the <code>CellEditor</code> to
     * the <code>delegate</code>.
     * @see EditorDelegate#stopCellEditing
     */

   
public boolean stopCellEditing() {
       
return delegate.stopCellEditing();
   
}

   
/**
     * Forwards the message from the <code>CellEditor</code> to
     * the <code>delegate</code>.
     * @see EditorDelegate#cancelCellEditing
     */

   
public void cancelCellEditing() {
       
delegate.cancelCellEditing();
   
}

//
//  Implementing the TreeCellEditor Interface
//

   
/** Implements the <code>TreeCellEditor</code> interface. */
   
public Component getTreeCellEditorComponent(JTree tree, Object value,
                                               
boolean isSelected,
                                               
boolean expanded,
                                               
boolean leaf, int row) {
       
String         stringValue = tree.convertValueToText(value, isSelected,
                                            expanded
, leaf, row, false);

       
delegate.setValue(stringValue);
       
return editorComponent;
   
}

//
//  Implementing the CellEditor Interface
//
   
/** Implements the <code>TableCellEditor</code> interface. */
   
public Component getTableCellEditorComponent(JTable table, Object value,
                                                 
boolean isSelected,
                                                 
int row, int column) {
       
delegate.setValue(value);
       
if (editorComponent instanceof JCheckBox) {
           
//in order to avoid a "flashing" effect when clicking a checkbox
           
//in a table, it is important for the editor to have as a border
           
//the same border that the renderer has, and have as the background
           
//the same color as the renderer has. This is primarily only
           
//needed for JCheckBox since this editor doesn't fill all the
           
//visual space of the table cell, unlike a text field.
           
TableCellRenderer renderer = table.getCellRenderer(row, column);
           
Component c = renderer.getTableCellRendererComponent(table, value,
                    isSelected
, true, row, column);
           
if (c != null) {
                editorComponent
.setOpaque(true);
                editorComponent
.setBackground(c.getBackground());
               
if (c instanceof JComponent) {
                    editorComponent
.setBorder(((JComponent)c).getBorder());
               
}
           
} else {
                editorComponent
.setOpaque(false);
           
}
       
}
       
return editorComponent;
   
}


//
//  Protected EditorDelegate class
//

   
/**
     * The protected <code>EditorDelegate</code> class.
     */

   
protected class EditorDelegate implements ActionListener, ItemListener, Serializable {

       
/**  The value of this cell. */
       
protected Object value;

       
/**
        * Returns the value of this cell.
        * @return the value of this cell
        */

       
public Object getCellEditorValue() {
           
return value;
       
}

       
/**
        * Sets the value of this cell.
        * @param value the new value of this cell
        */

       
public void setValue(Object value) {
           
this.value = value;
       
}

       
/**
        * Returns true if <code>anEvent</code> is <b>not</b> a
        * <code>MouseEvent</code>.  Otherwise, it returns true
        * if the necessary number of clicks have occurred, and
        * returns false otherwise.
        *
        * @param   anEvent         the event
        * @return  true  if cell is ready for editing, false otherwise
        * @see #setClickCountToStart
        * @see #shouldSelectCell
        */

       
public boolean isCellEditable(EventObject anEvent) {
           
if (anEvent instanceof MouseEvent) {
               
return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
           
}
           
return true;
       
}

       
/**
        * Returns true to indicate that the editing cell may
        * be selected.
        *
        * @param   anEvent         the event
        * @return  true
        * @see #isCellEditable
        */

       
public boolean shouldSelectCell(EventObject anEvent) {
           
return true;
       
}

       
/**
        * Returns true to indicate that editing has begun.
        *
        * @param anEvent          the event
        */

       
public boolean startCellEditing(EventObject anEvent) {
           
return true;
       
}

       
/**
        * Stops editing and
        * returns true to indicate that editing has stopped.
        * This method calls <code>fireEditingStopped</code>.
        *
        * @return  true
        */

       
public boolean stopCellEditing() {
            fireEditingStopped
();
           
return true;
       
}

       
/**
        * Cancels editing.  This method calls <code>fireEditingCanceled</code>.
        */

       
public void cancelCellEditing() {
           fireEditingCanceled
();
       
}

       
/**
        * When an action is performed, editing is ended.
        * @param e the action event
        * @see #stopCellEditing
        */

       
public void actionPerformed(ActionEvent e) {
           
DefaultCellEditor.this.stopCellEditing();
       
}

       
/**
        * When an item's state changes, editing is ended.
        * @param e the action event
        * @see #stopCellEditing
        */

       
public void itemStateChanged(ItemEvent e) {
           
DefaultCellEditor.this.stopCellEditing();
       
}
   
}

} // End of class JCellEditor