1. /*
  2. * @(#)DefaultCellEditor.java 1.50 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.Component;
  9. import java.awt.event.*;
  10. import java.awt.AWTEvent;
  11. import java.lang.Boolean;
  12. import javax.swing.table.*;
  13. import javax.swing.event.*;
  14. import java.util.EventObject;
  15. import javax.swing.tree.*;
  16. import java.io.Serializable;
  17. /**
  18. * The default editor for table and tree cells.
  19. * <p>
  20. * <strong>Warning:</strong>
  21. * Serialized objects of this class will not be compatible with
  22. * future Swing releases. The current serialization support is
  23. * appropriate for short term storage or RMI between applications running
  24. * the same version of Swing. As of 1.4, support for long term storage
  25. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  26. * has been added to the <code>java.beans</code> package.
  27. * Please see {@link java.beans.XMLEncoder}.
  28. *
  29. * @version 1.50 12/19/03
  30. * @author Alan Chung
  31. * @author Philip Milne
  32. */
  33. public class DefaultCellEditor extends AbstractCellEditor
  34. implements TableCellEditor, TreeCellEditor {
  35. //
  36. // Instance Variables
  37. //
  38. /** The Swing component being edited. */
  39. protected JComponent editorComponent;
  40. /**
  41. * The delegate class which handles all methods sent from the
  42. * <code>CellEditor</code>.
  43. */
  44. protected EditorDelegate delegate;
  45. /**
  46. * An integer specifying the number of clicks needed to start editing.
  47. * Even if <code>clickCountToStart</code> is defined as zero, it
  48. * will not initiate until a click occurs.
  49. */
  50. protected int clickCountToStart = 1;
  51. //
  52. // Constructors
  53. //
  54. /**
  55. * Constructs a <code>DefaultCellEditor</code> that uses a text field.
  56. *
  57. * @param textField a <code>JTextField</code> object
  58. */
  59. public DefaultCellEditor(final JTextField textField) {
  60. editorComponent = textField;
  61. this.clickCountToStart = 2;
  62. delegate = new EditorDelegate() {
  63. public void setValue(Object value) {
  64. textField.setText((value != null) ? value.toString() : "");
  65. }
  66. public Object getCellEditorValue() {
  67. return textField.getText();
  68. }
  69. };
  70. textField.addActionListener(delegate);
  71. }
  72. /**
  73. * Constructs a <code>DefaultCellEditor</code> object that uses a check box.
  74. *
  75. * @param checkBox a <code>JCheckBox</code> object
  76. */
  77. public DefaultCellEditor(final JCheckBox checkBox) {
  78. editorComponent = checkBox;
  79. delegate = new EditorDelegate() {
  80. public void setValue(Object value) {
  81. boolean selected = false;
  82. if (value instanceof Boolean) {
  83. selected = ((Boolean)value).booleanValue();
  84. }
  85. else if (value instanceof String) {
  86. selected = value.equals("true");
  87. }
  88. checkBox.setSelected(selected);
  89. }
  90. public Object getCellEditorValue() {
  91. return Boolean.valueOf(checkBox.isSelected());
  92. }
  93. };
  94. checkBox.addActionListener(delegate);
  95. }
  96. /**
  97. * Constructs a <code>DefaultCellEditor</code> object that uses a
  98. * combo box.
  99. *
  100. * @param comboBox a <code>JComboBox</code> object
  101. */
  102. public DefaultCellEditor(final JComboBox comboBox) {
  103. editorComponent = comboBox;
  104. comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
  105. delegate = new EditorDelegate() {
  106. public void setValue(Object value) {
  107. comboBox.setSelectedItem(value);
  108. }
  109. public Object getCellEditorValue() {
  110. return comboBox.getSelectedItem();
  111. }
  112. public boolean shouldSelectCell(EventObject anEvent) {
  113. if (anEvent instanceof MouseEvent) {
  114. MouseEvent e = (MouseEvent)anEvent;
  115. return e.getID() != MouseEvent.MOUSE_DRAGGED;
  116. }
  117. return true;
  118. }
  119. public boolean stopCellEditing() {
  120. if (comboBox.isEditable()) {
  121. // Commit edited value.
  122. comboBox.actionPerformed(new ActionEvent(
  123. DefaultCellEditor.this, 0, ""));
  124. }
  125. return super.stopCellEditing();
  126. }
  127. };
  128. comboBox.addActionListener(delegate);
  129. }
  130. /**
  131. * Returns a reference to the editor component.
  132. *
  133. * @return the editor <code>Component</code>
  134. */
  135. public Component getComponent() {
  136. return editorComponent;
  137. }
  138. //
  139. // Modifying
  140. //
  141. /**
  142. * Specifies the number of clicks needed to start editing.
  143. *
  144. * @param count an int specifying the number of clicks needed to start editing
  145. * @see #getClickCountToStart
  146. */
  147. public void setClickCountToStart(int count) {
  148. clickCountToStart = count;
  149. }
  150. /**
  151. * Returns the number of clicks needed to start editing.
  152. * @return the number of clicks needed to start editing
  153. */
  154. public int getClickCountToStart() {
  155. return clickCountToStart;
  156. }
  157. //
  158. // Override the implementations of the superclass, forwarding all methods
  159. // from the CellEditor interface to our delegate.
  160. //
  161. /**
  162. * Forwards the message from the <code>CellEditor</code> to
  163. * the <code>delegate</code>.
  164. * @see EditorDelegate#getCellEditorValue
  165. */
  166. public Object getCellEditorValue() {
  167. return delegate.getCellEditorValue();
  168. }
  169. /**
  170. * Forwards the message from the <code>CellEditor</code> to
  171. * the <code>delegate</code>.
  172. * @see EditorDelegate#isCellEditable(EventObject)
  173. */
  174. public boolean isCellEditable(EventObject anEvent) {
  175. return delegate.isCellEditable(anEvent);
  176. }
  177. /**
  178. * Forwards the message from the <code>CellEditor</code> to
  179. * the <code>delegate</code>.
  180. * @see EditorDelegate#shouldSelectCell(EventObject)
  181. */
  182. public boolean shouldSelectCell(EventObject anEvent) {
  183. return delegate.shouldSelectCell(anEvent);
  184. }
  185. /**
  186. * Forwards the message from the <code>CellEditor</code> to
  187. * the <code>delegate</code>.
  188. * @see EditorDelegate#stopCellEditing
  189. */
  190. public boolean stopCellEditing() {
  191. return delegate.stopCellEditing();
  192. }
  193. /**
  194. * Forwards the message from the <code>CellEditor</code> to
  195. * the <code>delegate</code>.
  196. * @see EditorDelegate#cancelCellEditing
  197. */
  198. public void cancelCellEditing() {
  199. delegate.cancelCellEditing();
  200. }
  201. //
  202. // Implementing the TreeCellEditor Interface
  203. //
  204. /** Implements the <code>TreeCellEditor</code> interface. */
  205. public Component getTreeCellEditorComponent(JTree tree, Object value,
  206. boolean isSelected,
  207. boolean expanded,
  208. boolean leaf, int row) {
  209. String stringValue = tree.convertValueToText(value, isSelected,
  210. expanded, leaf, row, false);
  211. delegate.setValue(stringValue);
  212. return editorComponent;
  213. }
  214. //
  215. // Implementing the CellEditor Interface
  216. //
  217. /** Implements the <code>TableCellEditor</code> interface. */
  218. public Component getTableCellEditorComponent(JTable table, Object value,
  219. boolean isSelected,
  220. int row, int column) {
  221. delegate.setValue(value);
  222. return editorComponent;
  223. }
  224. //
  225. // Protected EditorDelegate class
  226. //
  227. /**
  228. * The protected <code>EditorDelegate</code> class.
  229. */
  230. protected class EditorDelegate implements ActionListener, ItemListener, Serializable {
  231. /** The value of this cell. */
  232. protected Object value;
  233. /**
  234. * Returns the value of this cell.
  235. * @return the value of this cell
  236. */
  237. public Object getCellEditorValue() {
  238. return value;
  239. }
  240. /**
  241. * Sets the value of this cell.
  242. * @param value the new value of this cell
  243. */
  244. public void setValue(Object value) {
  245. this.value = value;
  246. }
  247. /**
  248. * Returns true if <code>anEvent</code> is <b>not</b> a
  249. * <code>MouseEvent</code>. Otherwise, it returns true
  250. * if the necessary number of clicks have occurred, and
  251. * returns false otherwise.
  252. *
  253. * @param anEvent the event
  254. * @return true if cell is ready for editing, false otherwise
  255. * @see #setClickCountToStart
  256. * @see #shouldSelectCell
  257. */
  258. public boolean isCellEditable(EventObject anEvent) {
  259. if (anEvent instanceof MouseEvent) {
  260. return ((MouseEvent)anEvent).getClickCount() >= clickCountToStart;
  261. }
  262. return true;
  263. }
  264. /**
  265. * Returns true to indicate that the editing cell may
  266. * be selected.
  267. *
  268. * @param anEvent the event
  269. * @return true
  270. * @see #isCellEditable
  271. */
  272. public boolean shouldSelectCell(EventObject anEvent) {
  273. return true;
  274. }
  275. /**
  276. * Returns true to indicate that editing has begun.
  277. *
  278. * @param anEvent the event
  279. */
  280. public boolean startCellEditing(EventObject anEvent) {
  281. return true;
  282. }
  283. /**
  284. * Stops editing and
  285. * returns true to indicate that editing has stopped.
  286. * This method calls <code>fireEditingStopped</code>.
  287. *
  288. * @return true
  289. */
  290. public boolean stopCellEditing() {
  291. fireEditingStopped();
  292. return true;
  293. }
  294. /**
  295. * Cancels editing. This method calls <code>fireEditingCanceled</code>.
  296. */
  297. public void cancelCellEditing() {
  298. fireEditingCanceled();
  299. }
  300. /**
  301. * When an action is performed, editing is ended.
  302. * @param e the action event
  303. * @see #stopCellEditing
  304. */
  305. public void actionPerformed(ActionEvent e) {
  306. DefaultCellEditor.this.stopCellEditing();
  307. }
  308. /**
  309. * When an item's state changes, editing is ended.
  310. * @param e the action event
  311. * @see #stopCellEditing
  312. */
  313. public void itemStateChanged(ItemEvent e) {
  314. DefaultCellEditor.this.stopCellEditing();
  315. }
  316. }
  317. } // End of class JCellEditor