Frames | No Frames |
1: /* DefaultCellEditor.java -- 2: Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Component; 42: import java.awt.event.ActionEvent; 43: import java.awt.event.ActionListener; 44: import java.awt.event.ItemEvent; 45: import java.awt.event.ItemListener; 46: import java.awt.event.MouseEvent; 47: import java.io.Serializable; 48: import java.util.EventObject; 49: 50: import javax.swing.JTable; 51: import javax.swing.JTextField; 52: import javax.swing.event.CellEditorListener; 53: import javax.swing.table.TableCellEditor; 54: import javax.swing.tree.TreeCellEditor; 55: 56: /** 57: * The default implementation of {@link TableCellEditor} and 58: * {@link TreeCellEditor}. It provides editor components for 59: * some standard object types. 60: * 61: * @author Andrew Selkirk 62: * @author Audrius Meskauskas 63: */ 64: public class DefaultCellEditor 65: extends AbstractCellEditor 66: implements TableCellEditor, TreeCellEditor 67: { 68: private static final long serialVersionUID = 3564035141373880027L; 69: 70: /** 71: * This changeable module access the editor component in the component 72: * specific way. For instance, to set the value for JTextField, we need to 73: * call setText(String), and for JCheckBox we need to call 74: * setSelected(boolean). Each default editor has the component specific 75: * derivative of this class. These derivatives are private inner classes of 76: * the DefaultCellEditor. 77: * 78: * The editor delegate is also set for the editor component as the action 79: * listener. It listens for the events that indicate that editing has stopped. 80: */ 81: protected class EditorDelegate 82: implements ActionListener, ItemListener, Serializable 83: { 84: /** 85: * Use the serial version UID for interoperability. 86: */ 87: private static final long serialVersionUID = -1420007406015481933L; 88: 89: /** 90: * The object value (updated when getting and setting the value). 91: */ 92: protected Object value; 93: 94: /** 95: * Constructor EditorDelegate 96: */ 97: protected EditorDelegate() 98: { 99: // Nothing to do here. 100: } 101: 102: /** 103: * Set the value for the editor component. This method is normally 104: * overridden to set the value in the way, specific for the text 105: * component, check box or combo box. 106: * 107: * @param aValue the value to set (String, Boolean or Number). 108: */ 109: public void setValue(Object aValue) 110: { 111: value = aValue; 112: } 113: 114: /** 115: * Get the value for the editor component. This method is normally 116: * overridden to obtain the value in the way, specific for the text 117: * component, check box or combo box. 118: * 119: * @return value the value of the component (String, Boolean or Number). 120: */ 121: public Object getCellEditorValue() 122: { 123: return value; 124: } 125: 126: /** 127: * The default method returns true for the {@link MouseEvent} and false 128: * for any other events. 129: * 130: * @param event the event to check 131: * 132: * @return true if the passed event is the mouse event and false otherwise. 133: */ 134: public boolean isCellEditable(EventObject event) 135: { 136: if (event == null || !(event instanceof MouseEvent) || 137: (((MouseEvent) event).getClickCount() >= getClickCountToStart())) 138: return true; 139: return false; 140: } // isCellEditable() 141: 142: /** 143: * Returns true to indicate that the editing cell can be selected. 144: * 145: * The default method returns true without action but may be overridden 146: * in derived classes for more specific behavior. 147: * 148: * @param event unused in default method 149: * 150: * @return true always 151: */ 152: public boolean shouldSelectCell(EventObject event) 153: { 154: // return true to indicate that the editing cell may be selected 155: return true; 156: } 157: 158: /** 159: * Finish the cell editing session. This method notifies the registered 160: * cell editor listeners (including the table) that the editing has been 161: * stopped. 162: * 163: * @return boolean 164: */ 165: public boolean stopCellEditing() 166: { 167: fireEditingStopped(); 168: return true; 169: } // stopCellEditing() 170: 171: /** 172: * Cancel the cell editing session. This method notifies the registered 173: * cell editor listeners (including the table) that the editing has been 174: * canceled. 175: */ 176: public void cancelCellEditing() 177: { 178: fireEditingCanceled(); 179: } // cancelCellEditing() 180: 181: /** 182: * Start editing session and returns true to indicate the editing has begun. 183: * The default method returns true without action but may be overridden 184: * in derived classes for more specific behavior. 185: * 186: * @param event the event. 187: * 188: * @return true, always 189: */ 190: public boolean startCellEditing(EventObject event) 191: { 192: // return true to indicate that editing has begun 193: return true; 194: } // startCellEditing() 195: 196: /** 197: * This event is fired by the editor component (for instance, by pressing 198: * ENTER in the {@link JTextField}. The default method delegates call to 199: * the {@link #stopCellEditing}, finishing the editing session. 200: * 201: * @param event unused in default method 202: */ 203: public void actionPerformed(ActionEvent event) 204: { 205: stopCellEditing(); 206: } // actionPerformed() 207: 208: /** 209: * This event is fired by the editor component.The default method delegates 210: * call to the {@link #stopCellEditing}, finishing the editing session. 211: * 212: * @param event unused in default method 213: */ 214: public void itemStateChanged(ItemEvent event) 215: { 216: stopCellEditing(); 217: } // itemStateChanged() 218: 219: /** 220: * Notify the registered listeners (including the table) that the editing 221: * has been completed. 222: */ 223: void fireEditingStopped() 224: { 225: CellEditorListener[] listeners = getCellEditorListeners(); 226: for (int index = 0; index < listeners.length; index++) 227: listeners[index].editingStopped(changeEvent); 228: 229: } 230: 231: /** 232: * Notify the registered listeners (including the table) that the editing 233: * has been canceled. 234: */ 235: void fireEditingCanceled() 236: { 237: CellEditorListener[] listeners = getCellEditorListeners(); 238: for (int index = 0; index < listeners.length; index++) 239: listeners[index].editingCanceled(changeEvent); 240: } 241: } // EditorDelegate 242: 243: /** 244: * Provides getter and setter methods to work with the text component. 245: * 246: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) 247: */ 248: private class JTextFieldDelegate extends EditorDelegate 249: { 250: /** 251: * Use the serial version UID for interoperability. 252: */ 253: private static final long serialVersionUID = 1; 254: 255: /** 256: * Set the value for the editor component. 257: * 258: * @param aValue the value to set (toString() will be called). 259: */ 260: public void setValue(Object aValue) 261: { 262: value = aValue; 263: JTextField f = (JTextField) editorComponent; 264: if (value == null) 265: f.setText(""); 266: else 267: f.setText(value.toString()); 268: } 269: 270: /** 271: * Get the value for the editor component. 272: * 273: * @return value the value of the component (String) 274: */ 275: public Object getCellEditorValue() 276: { 277: JTextField f = (JTextField) editorComponent; 278: return value = f.getText(); 279: } 280: } 281: 282: /** 283: * Provides getter and setter methods to work with the combo box. 284: * 285: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) 286: */ 287: private class JComboBoxDelegate extends EditorDelegate 288: { 289: /** 290: * Use the serial version UID for interoperability. 291: */ 292: private static final long serialVersionUID = 1; 293: 294: /** 295: * Set the value for the editor component. 296: * 297: * @param aValue the value to set. 298: */ 299: public void setValue(Object aValue) 300: { 301: value = aValue; 302: JComboBox c = (JComboBox) editorComponent; 303: if (value != null) 304: c.setSelectedItem(value); 305: } 306: 307: /** 308: * Get the value for the editor component. 309: * 310: * @return value the value of the component (as String) 311: */ 312: public Object getCellEditorValue() 313: { 314: JComboBox c = (JComboBox) editorComponent; 315: return value = c.getSelectedItem(); 316: } 317: 318: /** 319: * Returns true to indicate that the editing cell can be selected. If the 320: * check box is not editable, expands it. If it is editable, brings 321: * focus to the editor field. 322: * 323: * @param event unused in default method 324: * 325: * @return true always 326: */ 327: public boolean shouldSelectCell(EventObject event) 328: { 329: JComboBox c = (JComboBox) editorComponent; 330: if (!c.isEditable) 331: c.showPopup(); 332: return true; 333: } 334: } 335: 336: /** 337: * Provides getter and setter methods to work with the check box. 338: * 339: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) 340: */ 341: private class JCheckBoxDelegate extends EditorDelegate 342: { 343: /** 344: * Use the serial version UID for interoperability. 345: */ 346: private static final long serialVersionUID = 1; 347: 348: /** 349: * Set the value for the editor component. 350: * 351: * @param value the value to set (must be Boolean). 352: */ 353: public void setValue(Object value) 354: { 355: JCheckBox c = (JCheckBox) editorComponent; 356: 357: if (value == null) 358: c.setSelected(false); 359: else 360: c.setSelected( ((Boolean) value).booleanValue()); 361: } 362: 363: /** 364: * Get the value for the editor component. 365: * 366: * @return value the value of the component (must be CharSequence) 367: */ 368: public Object getCellEditorValue() 369: { 370: JCheckBox c = (JCheckBox) editorComponent; 371: value = c.isSelected() ? Boolean.TRUE : Boolean.FALSE; 372: return value; 373: } 374: } 375: 376: /** 377: * The Swing JComponent, performing the editing session. 378: */ 379: protected JComponent editorComponent; 380: 381: /** 382: * The editor delegate, responsible for listening the {@link #editorComponent} 383: * events and getting/setting its value. 384: */ 385: protected EditorDelegate delegate; 386: 387: /** 388: * The number of the mouse clicks, required to start the editing session. 389: */ 390: protected int clickCountToStart; 391: 392: /** 393: * Create the DefaultCellEditor that uses the text field as its editor 394: * component (appropriate for the text content) 395: * 396: * @param textfield the text field as will be used as the editor component 397: */ 398: public DefaultCellEditor(JTextField textfield) 399: { 400: editorComponent = textfield; 401: clickCountToStart = 2; 402: delegate = new JTextFieldDelegate(); 403: textfield.addActionListener(delegate); 404: } // DefaultCellEditor() 405: 406: /** 407: * Constructor DefaultCellEditor that uses the checkbox (appropriate 408: * for boolean values) 409: * 410: * @param checkbox the checkbox that will be used with this editor. 411: */ 412: public DefaultCellEditor(JCheckBox checkbox) 413: { 414: editorComponent = checkbox; 415: clickCountToStart = 1; 416: delegate = new JCheckBoxDelegate(); 417: checkbox.addActionListener(delegate); 418: } // DefaultCellEditor() 419: 420: /** 421: * Constructor DefaultCellEditor that uses the combo box. 422: * 423: * @param combobox the combo box that will be used with this editor. 424: */ 425: public DefaultCellEditor(JComboBox combobox) 426: { 427: editorComponent = combobox; 428: clickCountToStart = 1; 429: delegate = new JComboBoxDelegate(); 430: combobox.addActionListener(delegate); 431: } // DefaultCellEditor() 432: 433: /** 434: * Get the component that performs the editing sessions. It is the same 435: * component that was passed in constructor. 436: * 437: * @return the component, performing the editing sessions. 438: */ 439: public Component getComponent() 440: { 441: return editorComponent; 442: } // getComponent() 443: 444: /** 445: * Get the number of mouse clicks, required to start the editing session. 446: * 447: * @return int the number of mouse clicks, required to start the session 448: */ 449: public int getClickCountToStart() 450: { 451: return clickCountToStart; 452: } // getClickCountToStart() 453: 454: /** 455: * Set the number of mouse clicks, required to start the editing session. 456: * 457: * @param count the number of clicks, required to start the session 458: */ 459: public void setClickCountToStart(int count) 460: { 461: clickCountToStart = count; 462: } // setClickCountToStart() 463: 464: /** 465: * Get the value, currently being displayed by the editor component. The 466: * call is forwarded to the {@link #delegate}. 467: * 468: * @return Object the value (class depends on the editor component) 469: */ 470: public Object getCellEditorValue() 471: { 472: return delegate.getCellEditorValue(); 473: } // getCellEditorValue() 474: 475: /** 476: * Forwards call to the {@link #delegate}. 477: * 478: * @param event forwarded to the delegate. 479: * 480: * @return boolean returned by delegate 481: */ 482: public boolean isCellEditable(EventObject event) 483: { 484: return delegate.isCellEditable(event); 485: } // isCellEditable() 486: 487: /** 488: * Forwards call to the {@link #delegate}. 489: * 490: * @param event forwarded to the delegate. 491: * 492: * @return boolean returned by delegate 493: */ 494: public boolean shouldSelectCell(EventObject event) 495: { 496: return delegate.shouldSelectCell(event); 497: } // shouldSelectCell() 498: 499: /** 500: * Forwards call to the {@link #delegate}. 501: * 502: * @return boolean returned by delegate 503: */ 504: public boolean stopCellEditing() 505: { 506: return delegate.stopCellEditing(); 507: } // stopCellEditing() 508: 509: /** 510: * Forwards call to the {@link #delegate}. 511: */ 512: public void cancelCellEditing() 513: { 514: delegate.cancelCellEditing(); 515: } // cancelCellEditing() 516: 517: /** 518: * Sets an initial value for the editor. 519: * This will cause the editor to stopEditing and lose any partially 520: * edited value if the editor is editing when this method is called. 521: * Returns the component that should be added to the client's Component 522: * hierarchy. Once installed in the client's hierarchy this component will 523: * then be able to draw and receive user input. 524: * 525: * @param tree - the JTree that is asking the editor to edit; this 526: * parameter can be null 527: * @param value - the value of the cell to be edited 528: * @param isSelected - true is the cell is to be renderer with selection 529: * highlighting 530: * @param expanded - true if the node is expanded 531: * @param leaf - true if the node is a leaf node 532: * @param row - the row index of the node being edited 533: * 534: * @return Component the component for editing 535: */ 536: public Component getTreeCellEditorComponent(JTree tree, Object value, 537: boolean isSelected, 538: boolean expanded, boolean leaf, 539: int row) 540: { 541: delegate.setValue(value); 542: return editorComponent; 543: } // getTreeCellEditorComponent() 544: 545: /** 546: * Get the cell editor component that will perform the editing session. If 547: * returned once, the same component is also returned on the repetetive calls 548: * again (reused). 549: * 550: * @param table the table where the editing is performed 551: * @param value the current value of the table. It is set as the initial 552: * component value. 553: * @param isSelected if true, the cell is currently selected 554: * @param row the row of the cell being edited 555: * @param column the column of the cell being edited 556: * 557: * @return Component the component that will perform the editing session 558: */ 559: public Component getTableCellEditorComponent(JTable table, Object value, 560: boolean isSelected, int row, 561: int column) 562: { 563: // NOTE: as specified by Sun, we don't call new() everytime, we return 564: // editorComponent on each call to getTableCellEditorComponent or 565: // getTreeCellEditorComponent. 566: delegate.setValue(value); 567: return editorComponent; 568: } // getTableCellEditorComponent() 569: 570: }