KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > internal > databinding > internal > swt > TextObservableValue


1 /*******************************************************************************
2  * Copyright (c) 2005, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Brad Reynolds (bug 135446)
11  * Brad Reynolds - bug 164653
12  *******************************************************************************/

13 package org.eclipse.jface.internal.databinding.internal.swt;
14
15 import org.eclipse.core.databinding.observable.Diffs;
16 import org.eclipse.core.databinding.observable.IObservable;
17 import org.eclipse.jface.internal.databinding.provisional.swt.AbstractSWTVetoableValue;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.VerifyEvent;
20 import org.eclipse.swt.events.VerifyListener;
21 import org.eclipse.swt.widgets.Event;
22 import org.eclipse.swt.widgets.Listener;
23 import org.eclipse.swt.widgets.Text;
24
25 /**
26  * {@link IObservable} implementation that wraps a {@link Text} widget. The time
27  * at which listeners should be notified about changes to the text is specified
28  * on construction.
29  *
30  * <dl>
31  * <dt>Events:</dt>
32  * <dd> If the update event type (specified on construction) is
33  * <code>SWT.Modify</code> a value change event will be fired on every key
34  * stroke. If the update event type is <code>SWT.FocusOut</code> a value
35  * change event will be fired on focus out. When in either mode if the user is
36  * entering text and presses [Escape] the value will be reverted back to the
37  * last value set using doSetValue(). Regardless of the update event type a
38  * value changing event will fire on verify to enable vetoing of changes.</dd>
39  * </dl>
40  *
41  * @since 1.0
42  */

43 public class TextObservableValue extends AbstractSWTVetoableValue {
44
45     /**
46      * {@link Text} widget that this is being observed.
47      */

48     private final Text text;
49
50     /**
51      * Flag to track when the model is updating the widget. When
52      * <code>true</code> the handlers for the SWT events should not process
53      * the event as this would cause an infinite loop.
54      */

55     private boolean updating = false;
56
57     /**
58      * SWT event that on firing this observable will fire change events to its
59      * listeners.
60      */

61     private final int updateEventType;
62
63     /**
64      * Valid types for the {@link #updateEventType}.
65      */

66     private static final int[] validUpdateEventTypes = new int[] { SWT.Modify,
67             SWT.FocusOut, SWT.NONE };
68
69     /**
70      * Previous value of the Text.
71      */

72     private String JavaDoc oldValue;
73
74     private Listener updateListener = new Listener() {
75         public void handleEvent(Event event) {
76             if (!updating) {
77                 String JavaDoc newValue = text.getText();
78
79                 if (!newValue.equals(oldValue)) {
80                     fireValueChange(Diffs.createValueDiff(oldValue, newValue));
81                     oldValue = newValue;
82                 }
83             }
84         }
85     };
86
87     private VerifyListener verifyListener;
88
89     /**
90      * Constructs a new instance bound to the given <code>text</code> widget
91      * and configured to fire change events to its listeners at the time of the
92      * <code>updateEventType</code>.
93      *
94      * @param text
95      * @param updateEventType
96      * SWT event constant as to what SWT event to update the model in
97      * response to. Appropriate values are: <code>SWT.Modify</code>,
98      * <code>SWT.FocusOut</code>, <code>SWT.NONE</code>.
99      * @throws IllegalArgumentException
100      * if <code>updateEventType</code> is an incorrect type.
101      */

102     public TextObservableValue(final Text text, int updateEventType) {
103         super(text);
104         boolean eventValid = false;
105         for (int i = 0; !eventValid && i < validUpdateEventTypes.length; i++) {
106             eventValid = (updateEventType == validUpdateEventTypes[i]);
107         }
108         if (!eventValid) {
109             throw new IllegalArgumentException JavaDoc(
110                     "UpdateEventType [" + updateEventType + "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
111
}
112         this.text = text;
113         this.updateEventType = updateEventType;
114         if (updateEventType != SWT.None) {
115             text.addListener(updateEventType, updateListener);
116         }
117         
118         oldValue = text.getText();
119         
120         verifyListener = new VerifyListener() {
121             public void verifyText(VerifyEvent e) {
122                 if (!updating) {
123                     String JavaDoc currentText = TextObservableValue.this.text
124                             .getText();
125                     String JavaDoc newText = currentText.substring(0, e.start) + e.text
126                             + currentText.substring(e.end);
127                     if (!fireValueChanging(Diffs.createValueDiff(currentText,
128                             newText))) {
129                         e.doit = false;
130                     }
131                 }
132             }
133         };
134         text.addVerifyListener(verifyListener);
135     }
136
137     /**
138      * Sets the bound {@link Text Text's} text to the passed <code>value</code>.
139      *
140      * @param value
141      * new value, String expected
142      * @see org.eclipse.core.databinding.observable.value.AbstractVetoableValue#doSetApprovedValue(java.lang.Object)
143      * @throws ClassCastException
144      * if the value is anything other than a String
145      */

146     protected void doSetApprovedValue(final Object JavaDoc value) {
147         try {
148             updating = true;
149             text.setText(value == null ? "" : value.toString()); //$NON-NLS-1$
150
oldValue = text.getText();
151         } finally {
152             updating = false;
153         }
154     }
155
156     /**
157      * Returns the current value of the {@link Text}.
158      *
159      * @see org.eclipse.core.databinding.observable.value.AbstractVetoableValue#doGetValue()
160      */

161     public Object JavaDoc doGetValue() {
162         return oldValue = text.getText();
163     }
164
165     /**
166      * Returns the type of the value from {@link #doGetValue()}, i.e.
167      * String.class
168      *
169      * @see org.eclipse.core.databinding.observable.value.IObservableValue#getValueType()
170      */

171     public Object JavaDoc getValueType() {
172         return String JavaDoc.class;
173     }
174
175     public void dispose() {
176         if (!text.isDisposed()) {
177             if (updateEventType != SWT.None) {
178                 text.removeListener(updateEventType, updateListener);
179             }
180             text.removeVerifyListener(verifyListener);
181         }
182         super.dispose();
183     }
184 }
185
Popular Tags