001: package net.xoetrope.builder.editor.components.swing;
002:
003: import java.util.EventObject;
004:
005: import java.awt.Component;
006: import javax.swing.JComboBox;
007: import javax.swing.JTable;
008: import javax.swing.event.CellEditorListener;
009: import javax.swing.table.TableCellEditor;
010: import java.awt.event.ActionListener;
011: import java.awt.event.ItemListener;
012: import java.io.Serializable;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ItemEvent;
015: import java.awt.event.MouseEvent;
016: import javax.swing.event.ChangeEvent;
017: import javax.swing.event.EventListenerList;
018: import net.xoetrope.xui.XListHolder;
019:
020: /**
021: * For the generation of survey screens
022: * <p>Copyright Xoetrope Ltd. (c) 2002-2003</p>
023: * $Revision: 1.2 $
024: */
025: public class XComboBoxEditor extends JComboBox implements
026: TableCellEditor {
027: /**
028: * An integer specifying the number of clicks needed to start editing.
029: * Even if <code>clickCountToStart</code> is defined as zero, it
030: * will not initiate until a click occurs.
031: */
032: protected int clickCountToStart = 1;
033:
034: protected EventListenerList listenerList = new EventListenerList();
035: transient protected ChangeEvent changeEvent = null;
036:
037: public XComboBoxEditor() {
038:
039: }
040:
041: public XComboBoxEditor(Object[] values) {
042: super (values);
043: }
044:
045: public Component getTableCellEditorComponent(JTable table,
046: Object value, boolean isSelected, int row, int column) {
047: if (isSelected) {
048: setForeground(table.getSelectionForeground());
049: setBackground(table.getSelectionBackground());
050: } else {
051: setForeground(table.getForeground());
052: setBackground(table.getBackground());
053: }
054: return this ;
055: }
056:
057: public void removeCellListener(CellEditorListener listener) {
058: }
059:
060: public void stopCellEditing(EventObject o) {
061: }
062:
063: public Object getCellEditorValue() {
064: return getSelectedItem();
065: }
066:
067: /**
068: * Returns true.
069: * @param e an event object
070: * @return true
071: */
072: public boolean isCellEditable(EventObject e) {
073: return true;
074: }
075:
076: /**
077: * Returns true.
078: * @param e an event object
079: * @return true
080: */
081: public boolean shouldSelectCell(EventObject anEvent) {
082: return true;
083: }
084:
085: /**
086: * Calls <code>fireEditingStopped</code> and returns true.
087: * @return true
088: */
089: public boolean stopCellEditing() {
090: fireEditingStopped();
091: return true;
092: }
093:
094: /**
095: * Calls <code>fireEditingCanceled</code>.
096: */
097: public void cancelCellEditing() {
098: fireEditingCanceled();
099: }
100:
101: /**
102: * Adds a <code>CellEditorListener</code> to the listener list.
103: * @param l the new listener to be added
104: */
105: public void addCellEditorListener(CellEditorListener l) {
106: listenerList.add(CellEditorListener.class, l);
107: }
108:
109: /**
110: * Removes a <code>CellEditorListener</code> from the listener list.
111: * @param l the listener to be removed
112: */
113: public void removeCellEditorListener(CellEditorListener l) {
114: listenerList.remove(CellEditorListener.class, l);
115: }
116:
117: /**
118: * Returns an array of all the <code>CellEditorListener</code>s added
119: * to this AbstractCellEditor with addCellEditorListener().
120: *
121: * @return all of the <code>CellEditorListener</code>s added or an empty
122: * array if no listeners have been added
123: * @since 1.4
124: */
125: public CellEditorListener[] getCellEditorListeners() {
126: return (CellEditorListener[]) listenerList
127: .getListeners(CellEditorListener.class);
128: }
129:
130: /**
131: * Notifies all listeners that have registered interest for
132: * notification on this event type. The event instance
133: * is created lazily.
134: *
135: * @see EventListenerList
136: */
137: protected void fireEditingStopped() {
138: // Guaranteed to return a non-null array
139: Object[] listeners = listenerList.getListenerList();
140: // Process the listeners last to first, notifying
141: // those that are interested in this event
142: for (int i = listeners.length - 2; i >= 0; i -= 2) {
143: if (listeners[i] == CellEditorListener.class) {
144: // Lazily create the event:
145: if (changeEvent == null)
146: changeEvent = new ChangeEvent(this );
147: ((CellEditorListener) listeners[i + 1])
148: .editingStopped(changeEvent);
149: }
150: }
151: }
152:
153: /**
154: * Notifies all listeners that have registered interest for
155: * notification on this event type. The event instance
156: * is created lazily.
157: *
158: * @see EventListenerList
159: */
160: protected void fireEditingCanceled() {
161: // Guaranteed to return a non-null array
162: Object[] listeners = listenerList.getListenerList();
163: // Process the listeners last to first, notifying
164: // those that are interested in this event
165: for (int i = listeners.length - 2; i >= 0; i -= 2) {
166: if (listeners[i] == CellEditorListener.class) {
167: // Lazily create the event:
168: if (changeEvent == null)
169: changeEvent = new ChangeEvent(this );
170: ((CellEditorListener) listeners[i + 1])
171: .editingCanceled(changeEvent);
172: }
173: }
174: }
175:
176: /**
177: * The protected <code>EditorDelegate</code> class.
178: */
179: protected class EditorDelegate implements ActionListener,
180: ItemListener, Serializable {
181:
182: /** The value of this cell. */
183: protected Object value;
184:
185: /**
186: * Returns the value of this cell.
187: * @return the value of this cell
188: */
189: public Object getCellEditorValue() {
190: return value;
191: }
192:
193: /**
194: * Sets the value of this cell.
195: * @param value the new value of this cell
196: */
197: public void setValue(Object value) {
198: this .value = value;
199: }
200:
201: /**
202: * Returns true if <code>anEvent</code> is <b>not</b> a
203: * <code>MouseEvent</code>. Otherwise, it returns true
204: * if the necessary number of clicks have occurred, and
205: * returns false otherwise.
206: *
207: * @param anEvent the event
208: * @return true if cell is ready for editing, false otherwise
209: * @see #setClickCountToStart
210: * @see #shouldSelectCell
211: */
212: public boolean isCellEditable(EventObject anEvent) {
213: if (anEvent instanceof MouseEvent) {
214: return ((MouseEvent) anEvent).getClickCount() >= clickCountToStart;
215: }
216: return true;
217: }
218:
219: /**
220: * Returns true to indicate that the editing cell may
221: * be selected.
222: *
223: * @param anEvent the event
224: * @return true
225: * @see #isCellEditable
226: */
227: public boolean shouldSelectCell(EventObject anEvent) {
228: return true;
229: }
230:
231: /**
232: * Returns true to indicate that editing has begun.
233: *
234: * @param anEvent the event
235: */
236: public boolean startCellEditing(EventObject anEvent) {
237: return true;
238: }
239:
240: /**
241: * Stops editing and
242: * returns true to indicate that editing has stopped.
243: * This method calls <code>fireEditingStopped</code>.
244: *
245: * @return true
246: */
247: public boolean stopCellEditing() {
248: fireEditingStopped();
249: return true;
250: }
251:
252: /**
253: * Cancels editing. This method calls <code>fireEditingCanceled</code>.
254: */
255: public void cancelCellEditing() {
256: fireEditingCanceled();
257: }
258:
259: /**
260: * When an action is performed, editing is ended.
261: * @param e the action event
262: * @see #stopCellEditing
263: */
264: public void actionPerformed(ActionEvent e) {
265: XComboBoxEditor.this .stopCellEditing();
266: }
267:
268: /**
269: * When an item's state changes, editing is ended.
270: * @param e the action event
271: * @see #stopCellEditing
272: */
273: public void itemStateChanged(ItemEvent e) {
274: XComboBoxEditor.this.stopCellEditing();
275: }
276: }
277: }
|