/* * @(#)DefaultCellEditor.java 1.52 05/08/09 * * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.swing; import java.awt.Component; import java.awt.event.*; import java.awt.AWTEvent; import java.lang.Boolean; import javax.swing.table.*; import javax.swing.event.*; import java.util.EventObject; import javax.swing.tree.*; import java.io.Serializable; import static com.sun.java.swing.SwingUtilities2.DRAG_FIX; /** * The default editor for table and tree cells. *
 * Warning:
 * 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 JavaBeansTM
 * has been added to the java.beans package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @version 1.52 08/09/05
 * @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
     * CellEditor.
     */
    protected EditorDelegate delegate;
    /**
     * An integer specifying the number of clicks needed to start editing.
     * Even if clickCountToStart is defined as zero, it
     * will not initiate until a click occurs.
     */
    protected int clickCountToStart = 1;
//
//  Constructors
//
    /**
     * Constructs a DefaultCellEditor that uses a text field.
     *
     * @param textField  a JTextField 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 DefaultCellEditor object that uses a check box.
     *
     * @param checkBox  a JCheckBox 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);
        if (DRAG_FIX) {
            checkBox.setRequestFocusEnabled(false);
        }
    }
    /**
     * Constructs a DefaultCellEditor object that uses a
     * combo box.
     *
     * @param comboBox  a JComboBox 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 Component
     */
    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 CellEditor to
     * the delegate.
     * @see EditorDelegate#getCellEditorValue
     */
    public Object getCellEditorValue() {
        return delegate.getCellEditorValue();
    }
    /**
     * Forwards the message from the CellEditor to
     * the delegate.
     * @see EditorDelegate#isCellEditable(EventObject)
     */
    public boolean isCellEditable(EventObject anEvent) { 
	return delegate.isCellEditable(anEvent); 
    }
    
    /**
     * Forwards the message from the CellEditor to
     * the delegate.
     * @see EditorDelegate#shouldSelectCell(EventObject)
     */
    public boolean shouldSelectCell(EventObject anEvent) { 
	return delegate.shouldSelectCell(anEvent); 
    }
    /**
     * Forwards the message from the CellEditor to
     * the delegate.
     * @see EditorDelegate#stopCellEditing
     */
    public boolean stopCellEditing() {
	return delegate.stopCellEditing();
    }
    /**
     * Forwards the message from the CellEditor to
     * the delegate.
     * @see EditorDelegate#cancelCellEditing
     */
    public void cancelCellEditing() {
	delegate.cancelCellEditing();
    }
//
//  Implementing the TreeCellEditor Interface
//
    /** Implements the TreeCellEditor 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 TableCellEditor interface. */
    public Component getTableCellEditorComponent(JTable table, Object value,
						 boolean isSelected,
						 int row, int column) {
        delegate.setValue(value);
	return editorComponent;
    }
//
//  Protected EditorDelegate class
//
    /**
     * The protected EditorDelegate 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 anEvent is not a
        * MouseEvent.  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 fireEditingStopped.
        *
        * @return  true 
        */
        public boolean stopCellEditing() { 
	    fireEditingStopped(); 
	    return true;
	}
       /**
        * Cancels editing.  This method calls fireEditingCanceled.
        */
       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