001: /* $Id: PropertyCellEditor.java 746 2006-11-08 13:34:23Z hengels $ */
002: package org.conform.wings;
003:
004: import org.conform.*;
005: import org.wings.*;
006: import org.wings.table.STableCellEditor;
007:
008: import javax.swing.event.*;
009: import java.awt.event.*;
010: import java.util.*;
011: import java.io.Serializable;
012:
013: public class PropertyCellEditor implements STableCellEditor {
014: /**
015: * The default ok button icon.
016: */
017: private static final SIcon OK_BUTTON_ICON = new SResourceIcon(
018: "toolbarButtonGraphics/general/Save16.gif");
019:
020: /**
021: * The default cancel button icon.
022: */
023: private static final SIcon CANCEL_BUTTON_ICON = new SResourceIcon(
024: "toolbarButtonGraphics/general/Stop16.gif");
025:
026: protected final SLabel messageLabel = new SLabel();
027: protected final SPanel editorForm = new SPanel();
028: protected final SButton ok = new SButton();
029: protected final SButton cancel = new SButton();
030: protected final EventListenerList listenerList = new EventListenerList();
031: protected boolean fireStoppedEvent = false;
032: protected boolean fireCanceledEvent = false;
033:
034: private final ActionListener fireEventListener = new FireEventListener();
035:
036: /**
037: * Fast edit support is editing with reduced interaction. E.g. a boolean
038: * value can only have to states, true or false. So if editing is started,
039: * the editor just flips the state and fires editing stopped.
040: */
041: private boolean fastEditSupport = true;
042:
043: protected EditorDelegate delegate;
044:
045: protected SComponent editorComponent;
046: private PropertyData propertyData;
047: private Editor editor;
048:
049: public PropertyCellEditor(Editor editor,
050: final PropertyMeta propertyMeta) {
051: this .editor = editor;
052: editorForm.add(messageLabel);
053: this .editorComponent = editor.createComponent(propertyMeta);
054: editorForm.add(this .editorComponent);
055: propertyData = new EditorPropertyData(propertyMeta);
056: this .editor.setPropertyData(this .editorComponent, propertyData);
057:
058: this .delegate = new EditorDelegate() {
059: public void setValue(Object v) {
060: super .setValue(v);
061: propertyData.setValue(v);
062: }
063:
064: public Object getCellEditorValue() {
065: return propertyData.getValue();
066: }
067:
068: public boolean stopCellEditing() {
069: return true;
070: }
071:
072: public boolean shouldSelectCell(EventObject anEvent) {
073: return true;
074: }
075: };
076:
077: initButtons();
078: }
079:
080: protected void initButtons() {
081: ok.addActionListener(fireEventListener);
082: ok.setIcon(OK_BUTTON_ICON);
083: ok.setToolTipText("ok");
084:
085: cancel.addActionListener(fireEventListener);
086: cancel.setIcon(CANCEL_BUTTON_ICON);
087: cancel.setToolTipText("cancel");
088:
089: editorForm.add(ok);
090: editorForm.add(cancel);
091: }
092:
093: /**
094: * Returns a reference to the editor component.
095: *
096: * @return the editor Component
097: */
098: public final SComponent getComponent() {
099: return editorComponent;
100: }
101:
102: public final SButton getOKButton() {
103: return ok;
104: }
105:
106: public final SButton getCancelButton() {
107: return cancel;
108: }
109:
110: /**
111: * Fast edit support is editing with reduced interaction. E.g. a boolean
112: * value can only have to states, true or false. So if editing is started,
113: * the editor just flips the state and fires editing stopped.
114: *
115: * @param b a <code>boolean</code> value
116: */
117: public final void setFastEdit(boolean b) {
118: fastEditSupport = b;
119: }
120:
121: /**
122: * Return if fast edit is activated.
123: *
124: * @return a <code>boolean</code> value
125: * @see #setFastEdit
126: */
127: public final boolean getFastEdit() {
128: return fastEditSupport;
129: }
130:
131: public Object getCellEditorValue() {
132: return delegate.getCellEditorValue();
133: }
134:
135: public boolean isCellEditable(EventObject anEvent) {
136: return delegate.isCellEditable(anEvent);
137: }
138:
139: public boolean shouldSelectCell(EventObject anEvent) {
140: return delegate.shouldSelectCell(anEvent);
141: }
142:
143: public boolean stopCellEditing() {
144: if (delegate.stopCellEditing()) {
145: fireEditingStopped();
146: return true;
147: }
148:
149: return false;
150: }
151:
152: public void cancelCellEditing() {
153: delegate.cancelCellEditing();
154: fireEditingCanceled();
155: }
156:
157: public void addCellEditorListener(CellEditorListener l) {
158: listenerList.add(CellEditorListener.class, l);
159: }
160:
161: public void removeCellEditorListener(CellEditorListener l) {
162: listenerList.remove(CellEditorListener.class, l);
163: }
164:
165: private ChangeEvent changeEvent = null;
166:
167: /*
168: * Notify all listeners that have registered interest for
169: * notification on this event type. The event instance
170: * is lazily created using the parameters passed into
171: * the fire method.
172: * @see EventListenerList
173: */
174: protected void fireEditingStopped() {
175: Object[] listeners = listenerList.getListenerList();
176: for (int i = listeners.length - 2; i >= 0; i -= 2) {
177: if (listeners[i] == CellEditorListener.class) {
178: if (changeEvent == null)
179: changeEvent = new ChangeEvent(this );
180: ((CellEditorListener) listeners[i + 1])
181: .editingStopped(changeEvent);
182: }
183: }
184: }
185:
186: /*
187: * Notify all listeners that have registered interest for
188: * notification on this event type. The event instance
189: * is lazily created using the parameters passed into
190: * the fire method.
191: * @see EventListenerList
192: */
193: protected void fireEditingCanceled() {
194: Object[] listeners = listenerList.getListenerList();
195: for (int i = listeners.length - 2; i >= 0; i -= 2) {
196: if (listeners[i] == CellEditorListener.class) {
197: if (changeEvent == null)
198: changeEvent = new ChangeEvent(this );
199: ((CellEditorListener) listeners[i + 1])
200: .editingCanceled(changeEvent);
201: }
202: }
203: }
204:
205: public boolean containedInForm(SComponent c) {
206: while (c != null) {
207: if (c instanceof SForm)
208: return true;
209: c = c.getParent();
210: }
211: return false;
212: }
213:
214: /*
215: public SComponent getTreeCellEditorComponent(STree tree, Object value,
216: boolean isSelected,
217: boolean expanded,
218: boolean leaf, int row) {
219:
220: String stringValue = (value != null)?value.toString():"";
221:
222: delegate.setValue(stringValue);
223: return editorForm;
224: }
225: */
226:
227: public SComponent getTableCellEditorComponent(STable table,
228: Object value, boolean isSelected, int row, int column) {
229: delegate.setValue(value);
230: return editorForm;
231: }
232:
233: protected static class EditorDelegate {
234: protected Object value;
235:
236: public Object getCellEditorValue() {
237: return value;
238: }
239:
240: /**
241: * Set the Editors value. The task of this method is to
242: * pass the value to the editor component so that editing
243: * can be started.
244: *
245: * @param x the value to be edited.
246: */
247: public void setValue(Object x) {
248: this .value = x;
249: }
250:
251: public boolean isCellEditable(EventObject anEvent) {
252: return true;
253: }
254:
255: public boolean stopCellEditing() {
256: return true;
257: }
258:
259: public void cancelCellEditing() {
260: }
261:
262: public boolean shouldSelectCell(EventObject anEvent) {
263: return true;
264: }
265: }
266:
267: private final class FireEventListener implements ActionListener,
268: Serializable {
269: /**
270: *
271: */
272: private static final long serialVersionUID = 1L;
273:
274: public void actionPerformed(ActionEvent e) {
275: if (e.getSource() == ok) {
276: stopCellEditing();
277: } else if (e.getSource() == cancel) {
278: cancelCellEditing();
279: }
280: }
281: }
282:
283: class EditorPropertyData extends AbstractPropertyData {
284: private Object value;
285: private Object invalidValue;
286:
287: protected EditorPropertyData(PropertyMeta propertyMeta) {
288: super (null, propertyMeta);
289: }
290:
291: public void setValue(Object value) {
292: this .value = value;
293: }
294:
295: public Object getValue() {
296: return value;
297: }
298:
299: public Data getRelationData() {
300: return null;
301: }
302:
303: public void setInvalidValue(Object text) {
304: invalidValue = text;
305: }
306:
307: protected void doSetValue(Object value) {
308: }
309:
310: protected Object doGetValue() {
311: return null;
312: }
313:
314: public Object getInvalidValue() {
315: return invalidValue;
316: }
317: }
318: }
|