001: package snow.sortabletable;
002:
003: import javax.swing.*;
004: import javax.swing.event.*;
005: import java.awt.*;
006: import java.awt.event.*;
007: import javax.swing.table.*;
008: import java.util.*;
009:
010: /** our own table cell editor (based on DefaultCellEditor) using a textfield
011: keeping the types passed (Integer, Float, Double)
012: selet all when focused, nicer behaviour.
013: */
014: public class NumberTableCellEditor extends JTextField implements
015: TableCellEditor, ActionListener {
016:
017: protected final Vector<CellEditorListener> listeners = new Vector<CellEditorListener>();
018:
019: // when a number is entered in a focused cell, it will be overwritten if true!
020: boolean selectAllWhenFocused = true;
021:
022: // kept to test for class
023: protected Object oldValue = null;
024:
025: public NumberTableCellEditor() {
026: super ();
027: //this.setInputVerifier(InputVerifier
028:
029: // To stop cell editing
030: this .addActionListener(this );
031:
032: if (selectAllWhenFocused) {
033: this .addFocusListener(new FocusAdapter() {
034: @Override
035: public void focusGained(FocusEvent e) {
036: selectAll();
037: }
038: });
039: }
040: }
041:
042: public Component getTableCellEditorComponent(JTable table,
043: Object value, boolean isSelected, int row, int column) {
044: // terminate editing
045: this .stopCellEditing();
046:
047: oldValue = value;
048: setText(value.toString());
049:
050: if (selectAllWhenFocused)
051: this .selectAll();
052:
053: return this ;
054: }
055:
056: /** called when enter is pressed
057: */
058: public void actionPerformed(ActionEvent e) {
059: stopCellEditing();
060: }
061:
062: //
063: // Celleditor interface impl
064: //
065:
066: /** Adds a listener to the list that's notified when the editor stops, or cancels editing.
067: */
068: public void addCellEditorListener(CellEditorListener l) {
069: listeners.add(l);
070: }
071:
072: /** Removes a listener from the list that's notified
073: */
074: public void removeCellEditorListener(CellEditorListener l) {
075: listeners.remove(l);
076: }
077:
078: /** Tells the editor to cancel editing and not accept any partially edited value.
079: */
080: public void cancelCellEditing() {
081: final ChangeEvent ce = new ChangeEvent(this );
082: CellEditorListener[] copy = listeners
083: .toArray(new CellEditorListener[listeners.size()]);
084: for (CellEditorListener cl : copy) {
085: cl.editingCanceled(ce);
086: }
087: }
088:
089: /** Returns the value contained in the editor.
090: */
091: public Object getCellEditorValue() {
092: if (oldValue == null) {
093: return this .getText();
094: }
095:
096: if (oldValue instanceof Integer) {
097: try {
098: return Integer.parseInt(this .getText());
099: } catch (Exception e) {
100:
101: }
102: }
103: if (oldValue instanceof Float) {
104: try {
105: return Float.parseFloat(this .getText());
106: } catch (NumberFormatException e) {
107: System.out.println("ERROR: cannot parse float from "
108: + this .getText());
109: }
110: }
111: if (oldValue instanceof Double) {
112: try {
113: return Double.parseDouble(this .getText());
114: } catch (NumberFormatException e) {
115: System.out
116: .println("NumberTableCellEditor.getCellEditorValue(): Bad double format: "
117: + e.getMessage());
118: }
119: }
120:
121: // IMPORTANT FOR ASE:
122: return this .getText();
123: }
124:
125: /** Asks the editor if it can start editing using anEvent.
126: anEvent is in the invoking component coordinate system.
127: The editor can not assume the Component returned by getCellEditorComponent
128: is installed. This method is intended for the use of client to avoid
129: the cost of setting up and installing the editor component if editing
130: is not possible. If editing can be started this method returns true.
131: */
132: public boolean isCellEditable(EventObject anEvent) {
133: return true;
134: }
135:
136: /** Returns true if the editing cell should be selected, false otherwise.
137: Typically, the return value is true, because is most cases the editing cell
138: should be selected. However, it is useful to return false to keep the
139: selection from changing for some types of edits. eg.
140: A table that contains a column of check boxes, the user might want to
141: be able to change those checkboxes without altering the selection.
142: (See Netscape Communicator for just such an example) Of course, it is
143: up to the client of the editor to use the return value, but it
144: doesn't need to if it doesn't want to.
145: */
146: public boolean shouldSelectCell(EventObject anEvent) {
147: return true;
148: }
149:
150: /** Tells the editor to stop editing and accept any partially edited
151: value as the value of the editor.
152: @return true if editing was stopped; false otherwise
153: */
154: public boolean stopCellEditing() {
155: final ChangeEvent ce = new ChangeEvent(this );
156: CellEditorListener[] copy = listeners
157: .toArray(new CellEditorListener[listeners.size()]);
158: for (CellEditorListener cl : copy) {
159: cl.editingStopped(ce);
160: }
161:
162: // ok, we always accept.. ###
163: return true;
164: }
165:
166: }
|