KickJava   Java API By Example, From Geeks To Geeks.

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


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.dialogs.DialogPage;
14 import org.eclipse.jface.dialogs.IDialogConstants;
15 import org.eclipse.jface.resource.JFaceResources;
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.jface.util.IPropertyChangeListener;
18 import org.eclipse.jface.util.PropertyChangeEvent;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.DisposeEvent;
21 import org.eclipse.swt.events.DisposeListener;
22 import org.eclipse.swt.graphics.FontMetrics;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.layout.GridLayout;
26 import org.eclipse.swt.widgets.Button;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Label;
30
31 /**
32  * Abstract base class for all field editors.
33  * <p>
34  * A field editor presents the value of a preference to the end
35  * user. The value is loaded from a preference store; if
36  * modified by the end user, the value is validated and eventually
37  * stored back to the preference store. A field editor reports
38  * an event when the value, or the validity of the value, changes.
39  * </p>
40  * <p>
41  * Field editors should be used in conjunction with a field
42  * editor preference page (<code>FieldEditorPreferencePage</code>)
43  * which coordinates everything and provides the message line
44  * which display messages emanating from the editor.
45  * </p>
46  * <p>
47  * This package contains ready-to-use field editors for various
48  * types of preferences:
49  * <ul>
50  * <li><code>BooleanFieldEditor</code> - booleans</li>
51  * <li><code>IntegerFieldEditor</code> - integers</li>
52  * <li><code>StringFieldEditor</code> - text strings</li>
53  * <li><code>RadioGroupFieldEditor</code> - enumerations</li>
54  * <li><code>ColorFieldEditor</code> - RGB colors</li>
55  * <li><code>FontFieldEditor</code> - fonts</li>
56  * <li><code>DirectoryFieldEditor</code> - directories</li>
57  * <li><code>FileFieldEditor</code> - files</li>
58  * <li><code>PathEditor</code> - paths</li>
59  * </ul>
60  * </p>
61  */

62 public abstract class FieldEditor {
63
64     /**
65      * Property name constant (value <code>"field_editor_is_valid"</code>)
66      * to signal a change in the validity of the value of this field editor.
67      */

68     public static final String JavaDoc IS_VALID = "field_editor_is_valid";//$NON-NLS-1$
69

70     /**
71      * Property name constant (value <code>"field_editor_value"</code>)
72      * to signal a change in the value of this field editor.
73      */

74     public static final String JavaDoc VALUE = "field_editor_value";//$NON-NLS-1$
75

76     /**
77      * Gap between label and control.
78      */

79     protected static final int HORIZONTAL_GAP = 8;
80
81     /**
82      * The preference store, or <code>null</code> if none.
83      */

84     private IPreferenceStore preferenceStore = null;
85
86     /**
87      * The name of the preference displayed in this field editor.
88      */

89     private String JavaDoc preferenceName;
90
91     /**
92      * Indicates whether the default value is currently displayed,
93      * initially <code>false</code>.
94      */

95     private boolean isDefaultPresented = false;
96
97     /**
98      * The label's text.
99      */

100     private String JavaDoc labelText;
101
102     /**
103      * The label control.
104      */

105     private Label label;
106
107     /**
108      * Listener, or <code>null</code> if none
109      */

110     private IPropertyChangeListener propertyChangeListener;
111
112     /**
113      * The page containing this field editor
114      */

115     private DialogPage page;
116
117     /**
118      * Creates a new field editor.
119      */

120     protected FieldEditor() {
121     }
122
123     /**
124      * Creates a new field editor.
125      *
126      * @param name the name of the preference this field editor works on
127      * @param labelText the label text of the field editor
128      * @param parent the parent of the field editor's control
129      */

130     protected FieldEditor(String JavaDoc name, String JavaDoc labelText, Composite parent) {
131         init(name, labelText);
132         createControl(parent);
133     }
134
135     /**
136      * Adjusts the horizontal span of this field editor's basic controls.
137      * <p>
138      * Subclasses must implement this method to adjust the horizontal span
139      * of controls so they appear correct in the given number of columns.
140      * </p>
141      * <p>
142      * The number of columns will always be equal to or greater than the
143      * value returned by this editor's <code>getNumberOfControls</code> method.
144      *
145      * @param numColumns the number of columns
146      */

147     protected abstract void adjustForNumColumns(int numColumns);
148
149     /**
150      * Applies a font.
151      * <p>
152      * The default implementation of this framework method
153      * does nothing. Subclasses should override this method
154      * if they want to change the font of the SWT control to
155      * a value different than the standard dialog font.
156      * </p>
157      */

158     protected void applyFont() {
159     }
160
161     /**
162      * Checks if the given parent is the current parent of the
163      * supplied control; throws an (unchecked) exception if they
164      * are not correctly related.
165      *
166      * @param control the control
167      * @param parent the parent control
168      */

169     protected void checkParent(Control control, Composite parent) {
170         Assert.isTrue(control.getParent() == parent, "Different parents");//$NON-NLS-1$
171
}
172
173     /**
174      * Clears the error message from the message line.
175      */

176     protected void clearErrorMessage() {
177         if (page != null) {
178             page.setErrorMessage(null);
179         }
180     }
181
182     /**
183      * Clears the normal message from the message line.
184      */

185     protected void clearMessage() {
186         if (page != null) {
187             page.setMessage(null);
188         }
189     }
190
191     /**
192      * Returns the number of pixels corresponding to the
193      * given number of horizontal dialog units.
194      * <p>
195      * Clients may call this framework method, but should not override it.
196      * </p>
197      *
198      * @param control the control being sized
199      * @param dlus the number of horizontal dialog units
200      * @return the number of pixels
201      */

202     protected int convertHorizontalDLUsToPixels(Control control, int dlus) {
203         GC gc = new GC(control);
204         gc.setFont(control.getFont());
205         int averageWidth = gc.getFontMetrics().getAverageCharWidth();
206         gc.dispose();
207
208         double horizontalDialogUnitSize = averageWidth * 0.25;
209
210         return (int) Math.round(dlus * horizontalDialogUnitSize);
211     }
212
213     /**
214      * Returns the number of pixels corresponding to the
215      * given number of vertical dialog units.
216      * <p>
217      * Clients may call this framework method, but should not override it.
218      * </p>
219      *
220      * @param control the control being sized
221      * @param dlus the number of vertical dialog units
222      * @return the number of pixels
223      */

224     protected int convertVerticalDLUsToPixels(Control control, int dlus) {
225         GC gc = new GC(control);
226         gc.setFont(control.getFont());
227         int height = gc.getFontMetrics().getHeight();
228         gc.dispose();
229
230         double verticalDialogUnitSize = height * 0.125;
231
232         return (int) Math.round(dlus * verticalDialogUnitSize);
233     }
234
235     /**
236      * Creates this field editor's main control containing all of its
237      * basic controls.
238      *
239      * @param parent the parent control
240      */

241     protected void createControl(Composite parent) {
242         GridLayout layout = new GridLayout();
243         layout.numColumns = getNumberOfControls();
244         layout.marginWidth = 0;
245         layout.marginHeight = 0;
246         layout.horizontalSpacing = HORIZONTAL_GAP;
247         parent.setLayout(layout);
248         doFillIntoGrid(parent, layout.numColumns);
249     }
250
251     /**
252      * Disposes the SWT resources used by this field editor.
253      */

254     public void dispose() {
255         // nothing to dispose
256
}
257
258     /**
259      * Fills this field editor's basic controls into the given parent.
260      * <p>
261      * Subclasses must implement this method to create the controls
262      * for this field editor.
263      * </p>
264      *
265      * @param parent the composite used as a parent for the basic controls;
266      * the parent's layout must be a <code>GridLayout</code>
267      * @param numColumns the number of columns
268      */

269     protected abstract void doFillIntoGrid(Composite parent, int numColumns);
270
271     /**
272      * Initializes this field editor with the preference value from
273      * the preference store.
274      * <p>
275      * Subclasses must implement this method to properly initialize
276      * the field editor.
277      * </p>
278      */

279     protected abstract void doLoad();
280
281     /**
282      * Initializes this field editor with the default preference value from
283      * the preference store.
284      * <p>
285      * Subclasses must implement this method to properly initialize
286      * the field editor.
287      * </p>
288      */

289     protected abstract void doLoadDefault();
290
291     /**
292      * Stores the preference value from this field editor into
293      * the preference store.
294      * <p>
295      * Subclasses must implement this method to save the entered value
296      * into the preference store.
297      * </p>
298      */

299     protected abstract void doStore();
300
301     /**
302      * Fills this field editor's basic controls into the given parent.
303      *
304      * @param parent the composite used as a parent for the basic controls;
305      * the parent's layout must be a <code>GridLayout</code>
306      * @param numColumns the number of columns
307      */

308     public void fillIntoGrid(Composite parent, int numColumns) {
309         Assert.isTrue(numColumns >= getNumberOfControls());
310         Assert.isTrue(parent.getLayout() instanceof GridLayout);
311         doFillIntoGrid(parent, numColumns);
312     }
313
314     /**
315      * Informs this field editor's listener, if it has one, about a change to
316      * one of this field editor's boolean-valued properties. Does nothing
317      * if the old and new values are the same.
318      *
319      * @param property the field editor property name,
320      * such as <code>VALUE</code> or <code>IS_VALID</code>
321      * @param oldValue the old value
322      * @param newValue the new value
323      */

324     protected void fireStateChanged(String JavaDoc property, boolean oldValue,
325             boolean newValue) {
326         if (oldValue == newValue) {
327             return;
328         }
329         fireValueChanged(property, oldValue ? Boolean.TRUE : Boolean.FALSE, newValue ? Boolean.TRUE : Boolean.FALSE);
330     }
331
332     /**
333      * Informs this field editor's listener, if it has one, about a change to
334      * one of this field editor's properties.
335      *
336      * @param property the field editor property name,
337      * such as <code>VALUE</code> or <code>IS_VALID</code>
338      * @param oldValue the old value object, or <code>null</code>
339      * @param newValue the new value, or <code>null</code>
340      */

341     protected void fireValueChanged(String JavaDoc property, Object JavaDoc oldValue,
342             Object JavaDoc newValue) {
343         if (propertyChangeListener == null) {
344             return;
345         }
346         propertyChangeListener.propertyChange(new PropertyChangeEvent(this,
347                 property, oldValue, newValue));
348     }
349
350     /**
351      * Returns the symbolic font name used by this field editor.
352      *
353      * @return the symbolic font name
354      */

355     public String JavaDoc getFieldEditorFontName() {
356         return JFaceResources.DIALOG_FONT;
357     }
358
359     /**
360      * Returns the label control.
361      *
362      * @return the label control, or <code>null</code>
363      * if no label control has been created
364      */

365     protected Label getLabelControl() {
366         return label;
367     }
368
369     /**
370      * Returns this field editor's label component.
371      * <p>
372      * The label is created if it does not already exist
373      * </p>
374      *
375      * @param parent the parent
376      * @return the label control
377      */

378     public Label getLabelControl(Composite parent) {
379         if (label == null) {
380             label = new Label(parent, SWT.LEFT);
381             label.setFont(parent.getFont());
382             String JavaDoc text = getLabelText();
383             if (text != null) {
384                 label.setText(text);
385             }
386             label.addDisposeListener(new DisposeListener() {
387                 public void widgetDisposed(DisposeEvent event) {
388                     label = null;
389                 }
390             });
391         } else {
392             checkParent(label, parent);
393         }
394         return label;
395     }
396
397     /**
398      * Returns this field editor's label text.
399      *
400      * @return the label text
401      */

402     public String JavaDoc getLabelText() {
403         return labelText;
404     }
405
406     /**
407      * Returns the number of basic controls this field editor consists of.
408      *
409      * @return the number of controls
410      */

411     public abstract int getNumberOfControls();
412
413     /**
414      * Returns the name of the preference this field editor operates on.
415      *
416      * @return the name of the preference
417      */

418     public String JavaDoc getPreferenceName() {
419         return preferenceName;
420     }
421
422     /**
423      * Returns the preference page in which this field editor
424      * appears.
425      *
426      * @return the preference page, or <code>null</code> if none
427      * @deprecated use #getPage()
428      */

429     protected PreferencePage getPreferencePage() {
430         if(page != null && page instanceof PreferencePage) {
431             return (PreferencePage) page;
432         }
433         return null;
434     }
435     
436     /**
437      * Return the DialogPage that the receiver is sending
438      * updates to.
439      *
440      * @return DialogPage or <code>null</code> if it
441      * has not been set.
442      *
443      * @since 3.1
444      */

445     protected DialogPage getPage(){
446         return page;
447     }
448
449     /**
450      * Returns the preference store used by this field editor.
451      *
452      * @return the preference store, or <code>null</code> if none
453      * @see #setPreferenceStore
454      */

455     public IPreferenceStore getPreferenceStore() {
456         return preferenceStore;
457     }
458
459     /**
460      * Initialize the field editor with the given preference name and label.
461      *
462      * @param name the name of the preference this field editor works on
463      * @param text the label text of the field editor
464      */

465     protected void init(String JavaDoc name, String JavaDoc text) {
466         Assert.isNotNull(name);
467         Assert.isNotNull(text);
468         preferenceName = name;
469         this.labelText = text;
470     }
471
472     /**
473      * Returns whether this field editor contains a valid value.
474      * <p>
475      * The default implementation of this framework method
476      * returns <code>true</code>. Subclasses wishing to perform
477      * validation should override both this method and
478      * <code>refreshValidState</code>.
479      * </p>
480      *
481      * @return <code>true</code> if the field value is valid,
482      * and <code>false</code> if invalid
483      * @see #refreshValidState()
484      */

485     public boolean isValid() {
486         return true;
487     }
488
489     /**
490      * Initializes this field editor with the preference value from
491      * the preference store.
492      */

493     public void load() {
494         if (preferenceStore != null) {
495             isDefaultPresented = false;
496             doLoad();
497             refreshValidState();
498         }
499     }
500
501     /**
502      * Initializes this field editor with the default preference value
503      * from the preference store.
504      */

505     public void loadDefault() {
506         if (preferenceStore != null) {
507             isDefaultPresented = true;
508             doLoadDefault();
509             refreshValidState();
510         }
511     }
512
513     /**
514      * Returns whether this field editor currently presents the
515      * default value for its preference.
516      *
517      * @return <code>true</code> if the default value is presented,
518      * and <code>false</code> otherwise
519      */

520     public boolean presentsDefaultValue() {
521         return isDefaultPresented;
522     }
523
524     /**
525      * Refreshes this field editor's valid state after a value change
526      * and fires an <code>IS_VALID</code> property change event if
527      * warranted.
528      * <p>
529      * The default implementation of this framework method does
530      * nothing. Subclasses wishing to perform validation should override
531      * both this method and <code>isValid</code>.
532      * </p>
533      *
534      * @see #isValid
535      */

536     protected void refreshValidState() {
537     }
538
539     /**
540      * Sets the focus to this field editor.
541      * <p>
542      * The default implementation of this framework method
543      * does nothing. Subclasses may reimplement.
544      * </p>
545      */

546     public void setFocus() {
547         // do nothing;
548
}
549
550     /**
551      * Sets this field editor's label text.
552      * The label is typically presented to the left of the entry field.
553      *
554      * @param text the label text
555      */

556     public void setLabelText(String JavaDoc text) {
557         Assert.isNotNull(text);
558         labelText = text;
559         if (label != null) {
560             label.setText(text);
561         }
562     }
563
564     /**
565      * Sets the name of the preference this field editor operates on.
566      * <p>
567      * The ability to change this allows the same field editor object
568      * to be reused for different preferences.
569      * </p>
570      * <p>
571      * For example: <p>
572      * <pre>
573      * ...
574      * editor.setPreferenceName("font");
575      * editor.load();
576      * </pre>
577      * </p>
578      *
579      * @param name the name of the preference
580      */

581     public void setPreferenceName(String JavaDoc name) {
582         preferenceName = name;
583     }
584
585     /**
586      * Sets the preference page in which this field editor
587      * appears.
588      *
589      * @param preferencePage the preference page, or <code>null</code> if none
590      * @deprecated use #setPage(DialogPage)
591      */

592     public void setPreferencePage(PreferencePage preferencePage) {
593         setPage(preferencePage);
594     }
595     
596
597     /**
598      * Set the page to be the receiver.
599      * @param dialogPage
600      *
601      * @since 3.1
602      */

603     public void setPage(DialogPage dialogPage) {
604         page = dialogPage;
605         
606     }
607
608     /**
609      * Sets the preference store used by this field editor.
610      *
611      * @param store the preference store, or <code>null</code> if none
612      * @see #getPreferenceStore
613      */

614     public void setPreferenceStore(IPreferenceStore store) {
615         preferenceStore = store;
616     }
617
618     /**
619      * Sets whether this field editor is presenting the default value.
620      *
621      * @param booleanValue <code>true</code> if the default value is being presented,
622      * and <code>false</code> otherwise
623      */

624     protected void setPresentsDefaultValue(boolean booleanValue) {
625         isDefaultPresented = booleanValue;
626     }
627
628     /**
629      * Sets or removes the property change listener for this field editor.
630      * <p>
631      * Note that field editors can support only a single listener.
632      * </p>
633      *
634      * @param listener a property change listener, or <code>null</code>
635      * to remove
636      */

637     public void setPropertyChangeListener(IPropertyChangeListener listener) {
638         propertyChangeListener = listener;
639     }
640
641     /**
642      * Shows the given error message in the page for this
643      * field editor if it has one.
644      *
645      * @param msg the error message
646      */

647     protected void showErrorMessage(String JavaDoc msg) {
648         if (page != null) {
649             page.setErrorMessage(msg);
650         }
651     }
652
653     /**
654      * Shows the given message in the page for this
655      * field editor if it has one.
656      *
657      * @param msg the message
658      */

659     protected void showMessage(String JavaDoc msg) {
660         if (page != null) {
661             page.setErrorMessage(msg);
662         }
663     }
664
665     /**
666      * Stores this field editor's value back into the preference store.
667      */

668     public void store() {
669         if (preferenceStore == null) {
670             return;
671         }
672
673         if (isDefaultPresented) {
674             preferenceStore.setToDefault(preferenceName);
675         } else {
676             doStore();
677         }
678     }
679
680     /**
681      * Set the GridData on button to be one that is spaced for the
682      * current font.
683      * @param button the button the data is being set on.
684      */

685
686     protected void setButtonLayoutData(Button button) {
687
688         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
689
690         // Compute and store a font metric
691
GC gc = new GC(button);
692         gc.setFont(button.getFont());
693         FontMetrics fontMetrics = gc.getFontMetrics();
694         gc.dispose();
695
696         int widthHint = org.eclipse.jface.dialogs.Dialog
697                 .convertVerticalDLUsToPixels(fontMetrics,
698                         IDialogConstants.BUTTON_WIDTH);
699         data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
700                 SWT.DEFAULT, true).x);
701         button.setLayoutData(data);
702     }
703
704     /**
705      * Set whether or not the controls in the field editor
706      * are enabled.
707      * @param enabled The enabled state.
708      * @param parent The parent of the controls in the group.
709      * Used to create the controls if required.
710      */

711     public void setEnabled(boolean enabled, Composite parent) {
712         getLabelControl(parent).setEnabled(enabled);
713     }
714
715 }
716
Popular Tags