Path: blob/master/src/java.desktop/share/classes/javax/swing/DefaultCellEditor.java
41153 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.swing;2627import java.awt.Component;28import java.awt.event.*;29import java.beans.ConstructorProperties;30import java.lang.Boolean;31import javax.swing.table.*;32import javax.swing.event.*;33import java.util.EventObject;34import javax.swing.tree.*;35import java.io.Serializable;3637/**38* The default editor for table and tree cells.39* <p>40* <strong>Warning:</strong>41* Serialized objects of this class will not be compatible with42* future Swing releases. The current serialization support is43* appropriate for short term storage or RMI between applications running44* the same version of Swing. As of 1.4, support for long term storage45* of all JavaBeans46* has been added to the <code>java.beans</code> package.47* Please see {@link java.beans.XMLEncoder}.48*49* @author Alan Chung50* @author Philip Milne51* @since 1.252*/53@SuppressWarnings("serial") // Same-version serialization only54public class DefaultCellEditor extends AbstractCellEditor55implements TableCellEditor, TreeCellEditor {5657//58// Instance Variables59//6061/** The Swing component being edited. */62protected JComponent editorComponent;63/**64* The delegate class which handles all methods sent from the65* <code>CellEditor</code>.66*/67protected 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, it71* will not initiate until a click occurs.72*/73protected int clickCountToStart = 1;7475//76// Constructors77//7879/**80* Constructs a <code>DefaultCellEditor</code> that uses a text field.81*82* @param textField a <code>JTextField</code> object83*/84@ConstructorProperties({"component"})85public DefaultCellEditor(final JTextField textField) {86editorComponent = textField;87this.clickCountToStart = 2;88delegate = new EditorDelegate() {89public void setValue(Object value) {90textField.setText((value != null) ? value.toString() : "");91}9293public Object getCellEditorValue() {94return textField.getText();95}96};97textField.addActionListener(delegate);98}99100/**101* Constructs a <code>DefaultCellEditor</code> object that uses a check box.102*103* @param checkBox a <code>JCheckBox</code> object104*/105public DefaultCellEditor(final JCheckBox checkBox) {106editorComponent = checkBox;107delegate = new EditorDelegate() {108public void setValue(Object value) {109boolean selected = false;110if (value instanceof Boolean) {111selected = ((Boolean)value).booleanValue();112}113else if (value instanceof String) {114selected = value.equals("true");115}116checkBox.setSelected(selected);117}118119public Object getCellEditorValue() {120return Boolean.valueOf(checkBox.isSelected());121}122};123checkBox.addActionListener(delegate);124checkBox.setRequestFocusEnabled(false);125}126127/**128* Constructs a <code>DefaultCellEditor</code> object that uses a129* combo box.130*131* @param comboBox a <code>JComboBox</code> object132*/133public DefaultCellEditor(final JComboBox<?> comboBox) {134editorComponent = comboBox;135comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);136delegate = new EditorDelegate() {137public void setValue(Object value) {138comboBox.setSelectedItem(value);139}140141public Object getCellEditorValue() {142return comboBox.getSelectedItem();143}144145public boolean shouldSelectCell(EventObject anEvent) {146if (anEvent instanceof MouseEvent) {147MouseEvent e = (MouseEvent)anEvent;148return e.getID() != MouseEvent.MOUSE_DRAGGED;149}150return true;151}152public boolean stopCellEditing() {153if (comboBox.isEditable()) {154// Commit edited value.155comboBox.actionPerformed(new ActionEvent(156DefaultCellEditor.this, 0, ""));157}158return super.stopCellEditing();159}160};161comboBox.addActionListener(delegate);162}163164/**165* Returns a reference to the editor component.166*167* @return the editor <code>Component</code>168*/169public Component getComponent() {170return editorComponent;171}172173//174// Modifying175//176177/**178* Specifies the number of clicks needed to start editing.179*180* @param count an int specifying the number of clicks needed to start editing181* @see #getClickCountToStart182*/183public void setClickCountToStart(int count) {184clickCountToStart = count;185}186187/**188* Returns the number of clicks needed to start editing.189* @return the number of clicks needed to start editing190*/191public int getClickCountToStart() {192return clickCountToStart;193}194195//196// Override the implementations of the superclass, forwarding all methods197// from the CellEditor interface to our delegate.198//199200/**201* Forwards the message from the <code>CellEditor</code> to202* the <code>delegate</code>.203* @see EditorDelegate#getCellEditorValue204*/205public Object getCellEditorValue() {206return delegate.getCellEditorValue();207}208209/**210* Forwards the message from the <code>CellEditor</code> to211* the <code>delegate</code>.212* @see EditorDelegate#isCellEditable(EventObject)213*/214public boolean isCellEditable(EventObject anEvent) {215return delegate.isCellEditable(anEvent);216}217218/**219* Forwards the message from the <code>CellEditor</code> to220* the <code>delegate</code>.221* @see EditorDelegate#shouldSelectCell(EventObject)222*/223public boolean shouldSelectCell(EventObject anEvent) {224return delegate.shouldSelectCell(anEvent);225}226227/**228* Forwards the message from the <code>CellEditor</code> to229* the <code>delegate</code>.230* @see EditorDelegate#stopCellEditing231*/232public boolean stopCellEditing() {233return delegate.stopCellEditing();234}235236/**237* Forwards the message from the <code>CellEditor</code> to238* the <code>delegate</code>.239* @see EditorDelegate#cancelCellEditing240*/241public void cancelCellEditing() {242delegate.cancelCellEditing();243}244245//246// Implementing the TreeCellEditor Interface247//248249/** Implements the <code>TreeCellEditor</code> interface. */250public Component getTreeCellEditorComponent(JTree tree, Object value,251boolean isSelected,252boolean expanded,253boolean leaf, int row) {254String stringValue = tree.convertValueToText(value, isSelected,255expanded, leaf, row, false);256257delegate.setValue(stringValue);258return editorComponent;259}260261//262// Implementing the CellEditor Interface263//264/** Implements the <code>TableCellEditor</code> interface. */265public Component getTableCellEditorComponent(JTable table, Object value,266boolean isSelected,267int row, int column) {268delegate.setValue(value);269if (editorComponent instanceof JCheckBox) {270//in order to avoid a "flashing" effect when clicking a checkbox271//in a table, it is important for the editor to have as a border272//the same border that the renderer has, and have as the background273//the same color as the renderer has. This is primarily only274//needed for JCheckBox since this editor doesn't fill all the275//visual space of the table cell, unlike a text field.276TableCellRenderer renderer = table.getCellRenderer(row, column);277Component c = renderer.getTableCellRendererComponent(table, value,278isSelected, true, row, column);279if (c != null) {280editorComponent.setOpaque(true);281editorComponent.setBackground(c.getBackground());282if (c instanceof JComponent) {283editorComponent.setBorder(((JComponent)c).getBorder());284}285} else {286editorComponent.setOpaque(false);287}288}289return editorComponent;290}291292293//294// Protected EditorDelegate class295//296297/**298* The protected <code>EditorDelegate</code> class.299*/300protected class EditorDelegate implements ActionListener, ItemListener, Serializable {301302/** The value of this cell. */303protected Object value;304305/**306* Constructs an {@code EditorDelegate}.307*/308protected EditorDelegate() {}309310/**311* Returns the value of this cell.312* @return the value of this cell313*/314public Object getCellEditorValue() {315return value;316}317318/**319* Sets the value of this cell.320* @param value the new value of this cell321*/322public void setValue(Object value) {323this.value = value;324}325326/**327* Returns true if <code>anEvent</code> is <b>not</b> a328* <code>MouseEvent</code>. Otherwise, it returns true329* if the necessary number of clicks have occurred, and330* returns false otherwise.331*332* @param anEvent the event333* @return true if cell is ready for editing, false otherwise334* @see #setClickCountToStart335* @see #shouldSelectCell336*/337public boolean isCellEditable(EventObject anEvent) {338if (anEvent instanceof MouseEvent) {339return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;340}341return true;342}343344/**345* Returns true to indicate that the editing cell may346* be selected.347*348* @param anEvent the event349* @return true350* @see #isCellEditable351*/352public boolean shouldSelectCell(EventObject anEvent) {353return true;354}355356/**357* Returns true to indicate that editing has begun.358*359* @param anEvent the event360* @return true to indicate editing has begun361*/362public boolean startCellEditing(EventObject anEvent) {363return true;364}365366/**367* Stops editing and368* returns true to indicate that editing has stopped.369* This method calls <code>fireEditingStopped</code>.370*371* @return true372*/373public boolean stopCellEditing() {374fireEditingStopped();375return true;376}377378/**379* Cancels editing. This method calls <code>fireEditingCanceled</code>.380*/381public void cancelCellEditing() {382fireEditingCanceled();383}384385/**386* When an action is performed, editing is ended.387* @param e the action event388* @see #stopCellEditing389*/390public void actionPerformed(ActionEvent e) {391DefaultCellEditor.this.stopCellEditing();392}393394/**395* When an item's state changes, editing is ended.396* @param e the action event397* @see #stopCellEditing398*/399public void itemStateChanged(ItemEvent e) {400DefaultCellEditor.this.stopCellEditing();401}402}403404} // End of class JCellEditor405406407