KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > preference > StringFieldEditor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.jface.preference;
12
13 import org.eclipse.jface.resource.JFaceResources;
14 import org.eclipse.core.runtime.Assert;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.events.DisposeEvent;
17 import org.eclipse.swt.events.DisposeListener;
18 import org.eclipse.swt.events.FocusAdapter;
19 import org.eclipse.swt.events.FocusEvent;
20 import org.eclipse.swt.events.KeyAdapter;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.graphics.GC;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Text;
27
28 /**
29  * A field editor for a string type preference.
30  * <p>
31  * This class may be used as is, or subclassed as required.
32  * </p>
33  */

34 public class StringFieldEditor extends FieldEditor {
35
36     /**
37      * Validation strategy constant (value <code>0</code>) indicating that
38      * the editor should perform validation after every key stroke.
39      *
40      * @see #setValidateStrategy
41      */

42     public static final int VALIDATE_ON_KEY_STROKE = 0;
43
44     /**
45      * Validation strategy constant (value <code>1</code>) indicating that
46      * the editor should perform validation only when the text widget
47      * loses focus.
48      *
49      * @see #setValidateStrategy
50      */

51     public static final int VALIDATE_ON_FOCUS_LOST = 1;
52
53     /**
54      * Text limit constant (value <code>-1</code>) indicating unlimited
55      * text limit and width.
56      */

57     public static int UNLIMITED = -1;
58
59     /**
60      * Cached valid state.
61      */

62     private boolean isValid;
63
64     /**
65      * Old text value.
66      */

67     private String JavaDoc oldValue;
68
69     /**
70      * The text field, or <code>null</code> if none.
71      */

72     Text textField;
73
74     /**
75      * Width of text field in characters; initially unlimited.
76      */

77     private int widthInChars = UNLIMITED;
78
79     /**
80      * Text limit of text field in characters; initially unlimited.
81      */

82     private int textLimit = UNLIMITED;
83
84     /**
85      * The error message, or <code>null</code> if none.
86      */

87     private String JavaDoc errorMessage;
88
89     /**
90      * Indicates whether the empty string is legal;
91      * <code>true</code> by default.
92      */

93     private boolean emptyStringAllowed = true;
94
95     /**
96      * The validation strategy;
97      * <code>VALIDATE_ON_KEY_STROKE</code> by default.
98      */

99     private int validateStrategy = VALIDATE_ON_KEY_STROKE;
100
101     /**
102      * Creates a new string field editor
103      */

104     protected StringFieldEditor() {
105     }
106
107     /**
108      * Creates a string field editor.
109      * Use the method <code>setTextLimit</code> to limit the text.
110      *
111      * @param name the name of the preference this field editor works on
112      * @param labelText the label text of the field editor
113      * @param width the width of the text input field in characters,
114      * or <code>UNLIMITED</code> for no limit
115      * @param strategy either <code>VALIDATE_ON_KEY_STROKE</code> to perform
116      * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
117      * perform validation only after the text has been typed in
118      * @param parent the parent of the field editor's control
119      * @since 2.0
120      */

121     public StringFieldEditor(String JavaDoc name, String JavaDoc labelText, int width,
122             int strategy, Composite parent) {
123         init(name, labelText);
124         widthInChars = width;
125         setValidateStrategy(strategy);
126         isValid = false;
127         errorMessage = JFaceResources
128                 .getString("StringFieldEditor.errorMessage");//$NON-NLS-1$
129
createControl(parent);
130     }
131
132     /**
133      * Creates a string field editor.
134      * Use the method <code>setTextLimit</code> to limit the text.
135      *
136      * @param name the name of the preference this field editor works on
137      * @param labelText the label text of the field editor
138      * @param width the width of the text input field in characters,
139      * or <code>UNLIMITED</code> for no limit
140      * @param parent the parent of the field editor's control
141      */

142     public StringFieldEditor(String JavaDoc name, String JavaDoc labelText, int width,
143             Composite parent) {
144         this(name, labelText, width, VALIDATE_ON_KEY_STROKE, parent);
145     }
146
147     /**
148      * Creates a string field editor of unlimited width.
149      * Use the method <code>setTextLimit</code> to limit the text.
150      *
151      * @param name the name of the preference this field editor works on
152      * @param labelText the label text of the field editor
153      * @param parent the parent of the field editor's control
154      */

155     public StringFieldEditor(String JavaDoc name, String JavaDoc labelText, Composite parent) {
156         this(name, labelText, UNLIMITED, parent);
157     }
158
159     /* (non-Javadoc)
160      * Method declared on FieldEditor.
161      */

162     protected void adjustForNumColumns(int numColumns) {
163         GridData gd = (GridData) textField.getLayoutData();
164         gd.horizontalSpan = numColumns - 1;
165         // We only grab excess space if we have to
166
// If another field editor has more columns then
167
// we assume it is setting the width.
168
gd.grabExcessHorizontalSpace = gd.horizontalSpan == 1;
169     }
170
171     /**
172      * Checks whether the text input field contains a valid value or not.
173      *
174      * @return <code>true</code> if the field value is valid,
175      * and <code>false</code> if invalid
176      */

177     protected boolean checkState() {
178         boolean result = false;
179         if (emptyStringAllowed) {
180             result = true;
181         }
182
183         if (textField == null) {
184             result = false;
185         }
186
187         String JavaDoc txt = textField.getText();
188
189         result = (txt.trim().length() > 0) || emptyStringAllowed;
190
191         // call hook for subclasses
192
result = result && doCheckState();
193
194         if (result) {
195             clearErrorMessage();
196         } else {
197             showErrorMessage(errorMessage);
198         }
199
200         return result;
201     }
202
203     /**
204      * Hook for subclasses to do specific state checks.
205      * <p>
206      * The default implementation of this framework method does
207      * nothing and returns <code>true</code>. Subclasses should
208      * override this method to specific state checks.
209      * </p>
210      *
211      * @return <code>true</code> if the field value is valid,
212      * and <code>false</code> if invalid
213      */

214     protected boolean doCheckState() {
215         return true;
216     }
217
218     /**
219      * Fills this field editor's basic controls into the given parent.
220      * <p>
221      * The string field implementation of this <code>FieldEditor</code>
222      * framework method contributes the text field. Subclasses may override
223      * but must call <code>super.doFillIntoGrid</code>.
224      * </p>
225      */

226     protected void doFillIntoGrid(Composite parent, int numColumns) {
227         getLabelControl(parent);
228
229         textField = getTextControl(parent);
230         GridData gd = new GridData();
231         gd.horizontalSpan = numColumns - 1;
232         if (widthInChars != UNLIMITED) {
233             GC gc = new GC(textField);
234             try {
235                 Point extent = gc.textExtent("X");//$NON-NLS-1$
236
gd.widthHint = widthInChars * extent.x;
237             } finally {
238                 gc.dispose();
239             }
240         } else {
241             gd.horizontalAlignment = GridData.FILL;
242             gd.grabExcessHorizontalSpace = true;
243         }
244         textField.setLayoutData(gd);
245     }
246
247     /* (non-Javadoc)
248      * Method declared on FieldEditor.
249      */

250     protected void doLoad() {
251         if (textField != null) {
252             String JavaDoc value = getPreferenceStore().getString(getPreferenceName());
253             textField.setText(value);
254             oldValue = value;
255         }
256     }
257
258     /* (non-Javadoc)
259      * Method declared on FieldEditor.
260      */

261     protected void doLoadDefault() {
262         if (textField != null) {
263             String JavaDoc value = getPreferenceStore().getDefaultString(
264                     getPreferenceName());
265             textField.setText(value);
266         }
267         valueChanged();
268     }
269
270     /* (non-Javadoc)
271      * Method declared on FieldEditor.
272      */

273     protected void doStore() {
274         getPreferenceStore().setValue(getPreferenceName(), textField.getText());
275     }
276
277     /**
278      * Returns the error message that will be displayed when and if
279      * an error occurs.
280      *
281      * @return the error message, or <code>null</code> if none
282      */

283     public String JavaDoc getErrorMessage() {
284         return errorMessage;
285     }
286
287     /* (non-Javadoc)
288      * Method declared on FieldEditor.
289      */

290     public int getNumberOfControls() {
291         return 2;
292     }
293
294     /**
295      * Returns the field editor's value.
296      *
297      * @return the current value
298      */

299     public String JavaDoc getStringValue() {
300         if (textField != null) {
301             return textField.getText();
302         }
303         
304         return getPreferenceStore().getString(getPreferenceName());
305     }
306
307     /**
308      * Returns this field editor's text control.
309      *
310      * @return the text control, or <code>null</code> if no
311      * text field is created yet
312      */

313     protected Text getTextControl() {
314         return textField;
315     }
316
317     /**
318      * Returns this field editor's text control.
319      * <p>
320      * The control is created if it does not yet exist
321      * </p>
322      *
323      * @param parent the parent
324      * @return the text control
325      */

326     public Text getTextControl(Composite parent) {
327         if (textField == null) {
328             textField = new Text(parent, SWT.SINGLE | SWT.BORDER);
329             textField.setFont(parent.getFont());
330             switch (validateStrategy) {
331             case VALIDATE_ON_KEY_STROKE:
332                 textField.addKeyListener(new KeyAdapter() {
333
334                     /* (non-Javadoc)
335                      * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)
336                      */

337                     public void keyReleased(KeyEvent e) {
338                         valueChanged();
339                     }
340                 });
341
342                 break;
343             case VALIDATE_ON_FOCUS_LOST:
344                 textField.addKeyListener(new KeyAdapter() {
345                     public void keyPressed(KeyEvent e) {
346                         clearErrorMessage();
347                     }
348                 });
349                 textField.addFocusListener(new FocusAdapter() {
350                     public void focusGained(FocusEvent e) {
351                         refreshValidState();
352                     }
353
354                     public void focusLost(FocusEvent e) {
355                         valueChanged();
356                         clearErrorMessage();
357                     }
358                 });
359                 break;
360             default:
361                 Assert.isTrue(false, "Unknown validate strategy");//$NON-NLS-1$
362
}
363             textField.addDisposeListener(new DisposeListener() {
364                 public void widgetDisposed(DisposeEvent event) {
365                     textField = null;
366                 }
367             });
368             if (textLimit > 0) {//Only set limits above 0 - see SWT spec
369
textField.setTextLimit(textLimit);
370             }
371         } else {
372             checkParent(textField, parent);
373         }
374         return textField;
375     }
376
377     /**
378      * Returns whether an empty string is a valid value.
379      *
380      * @return <code>true</code> if an empty string is a valid value, and
381      * <code>false</code> if an empty string is invalid
382      * @see #setEmptyStringAllowed
383      */

384     public boolean isEmptyStringAllowed() {
385         return emptyStringAllowed;
386     }
387
388     /* (non-Javadoc)
389      * Method declared on FieldEditor.
390      */

391     public boolean isValid() {
392         return isValid;
393     }
394
395     /* (non-Javadoc)
396      * Method declared on FieldEditor.
397      */

398     protected void refreshValidState() {
399         isValid = checkState();
400     }
401
402     /**
403      * Sets whether the empty string is a valid value or not.
404      *
405      * @param b <code>true</code> if the empty string is allowed,
406      * and <code>false</code> if it is considered invalid
407      */

408     public void setEmptyStringAllowed(boolean b) {
409         emptyStringAllowed = b;
410     }
411
412     /**
413      * Sets the error message that will be displayed when and if
414      * an error occurs.
415      *
416      * @param message the error message
417      */

418     public void setErrorMessage(String JavaDoc message) {
419         errorMessage = message;
420     }
421
422     /* (non-Javadoc)
423      * Method declared on FieldEditor.
424      */

425     public void setFocus() {
426         if (textField != null) {
427             textField.setFocus();
428         }
429     }
430
431     /**
432      * Sets this field editor's value.
433      *
434      * @param value the new value, or <code>null</code> meaning the empty string
435      */

436     public void setStringValue(String JavaDoc value) {
437         if (textField != null) {
438             if (value == null) {
439                 value = "";//$NON-NLS-1$
440
}
441             oldValue = textField.getText();
442             if (!oldValue.equals(value)) {
443                 textField.setText(value);
444                 valueChanged();
445             }
446         }
447     }
448
449     /**
450      * Sets this text field's text limit.
451      *
452      * @param limit the limit on the number of character in the text
453      * input field, or <code>UNLIMITED</code> for no limit
454
455      */

456     public void setTextLimit(int limit) {
457         textLimit = limit;
458         if (textField != null) {
459             textField.setTextLimit(limit);
460         }
461     }
462
463     /**
464      * Sets the strategy for validating the text.
465      * <p>
466      * Calling this method has no effect after <code>createPartControl</code>
467      * is called. Thus this method is really only useful for subclasses to call
468      * in their constructor. However, it has public visibility for backward
469      * compatibility.
470      * </p>
471      *
472      * @param value either <code>VALIDATE_ON_KEY_STROKE</code> to perform
473      * on the fly checking (the default), or <code>VALIDATE_ON_FOCUS_LOST</code> to
474      * perform validation only after the text has been typed in
475      */

476     public void setValidateStrategy(int value) {
477         Assert.isTrue(value == VALIDATE_ON_FOCUS_LOST
478                 || value == VALIDATE_ON_KEY_STROKE);
479         validateStrategy = value;
480     }
481
482     /**
483      * Shows the error message set via <code>setErrorMessage</code>.
484      */

485     public void showErrorMessage() {
486         showErrorMessage(errorMessage);
487     }
488
489     /**
490      * Informs this field editor's listener, if it has one, about a change
491      * to the value (<code>VALUE</code> property) provided that the old and
492      * new values are different.
493      * <p>
494      * This hook is <em>not</em> called when the text is initialized
495      * (or reset to the default value) from the preference store.
496      * </p>
497      */

498     protected void valueChanged() {
499         setPresentsDefaultValue(false);
500         boolean oldState = isValid;
501         refreshValidState();
502
503         if (isValid != oldState) {
504             fireStateChanged(IS_VALID, oldState, isValid);
505         }
506
507         String JavaDoc newValue = textField.getText();
508         if (!newValue.equals(oldValue)) {
509             fireValueChanged(VALUE, oldValue, newValue);
510             oldValue = newValue;
511         }
512     }
513
514     /*
515      * @see FieldEditor.setEnabled(boolean,Composite).
516      */

517     public void setEnabled(boolean enabled, Composite parent) {
518         super.setEnabled(enabled, parent);
519         getTextControl(parent).setEnabled(enabled);
520     }
521 }
522
Popular Tags