KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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  * Chris Tilt (chris@tilts.net) - Bug 38547 - [Preferences] Changing preferences
11  * ignored after "Restore defaults" pressed.
12  *******************************************************************************/

13 package org.eclipse.jface.preference;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import org.eclipse.jface.resource.ImageDescriptor;
20 import org.eclipse.jface.util.IPropertyChangeListener;
21 import org.eclipse.jface.util.PropertyChangeEvent;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.layout.GridData;
24 import org.eclipse.swt.layout.GridLayout;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27
28 /**
29  * A special abstract preference page to host field editors.
30  * <p>
31  * Subclasses must implement the <code>createFieldEditors</code> method
32  * and should override <code>createLayout</code> if a special layout of the field
33  * editors is needed.
34  * </p>
35  */

36 public abstract class FieldEditorPreferencePage extends PreferencePage
37         implements IPropertyChangeListener {
38
39     /**
40      * Layout constant (value <code>0</code>) indicating that
41      * each field editor is handled as a single component.
42      */

43     public static final int FLAT = 0;
44
45     /**
46      * Layout constant (value <code>1</code>) indicating that
47      * the field editors' basic controls are put into a grid layout.
48      */

49     public static final int GRID = 1;
50
51     /**
52      * The vertical spacing used by layout styles <code>FLAT</code>
53      * and <code>GRID</code>.
54      */

55     protected static final int VERTICAL_SPACING = 10;
56
57     /**
58      * The margin width used by layout styles <code>FLAT</code>
59      * and <code>GRID</code>.
60      */

61     protected static final int MARGIN_WIDTH = 0;
62
63     /**
64      * The margin height used by layout styles <code>FLAT</code>
65      * and <code>GRID</code>.
66      */

67     protected static final int MARGIN_HEIGHT = 0;
68
69     /**
70      * The field editors, or <code>null</code> if not created yet.
71      */

72     private List JavaDoc fields = null;
73
74     /**
75      * The layout style; either <code>FLAT</code> or <code>GRID</code>.
76      */

77     private int style;
78
79     /**
80      * The first invalid field editor, or <code>null</code>
81      * if all field editors are valid.
82      */

83     private FieldEditor invalidFieldEditor = null;
84
85     /**
86      * The parent composite for field editors
87      */

88     private Composite fieldEditorParent;
89
90     /**
91      * Create a new instance of the reciever.
92      */

93     public FieldEditorPreferencePage() {
94         this(FLAT);
95     }
96
97     /**
98      * Creates a new field editor preference page with the given style,
99      * an empty title, and no image.
100      *
101      * @param style either <code>GRID</code> or <code>FLAT</code>
102      */

103     protected FieldEditorPreferencePage(int style) {
104         super();
105         this.style = style;
106     }
107
108     /**
109      * Creates a new field editor preference page with the given title
110      * and style, but no image.
111      *
112      * @param title the title of this preference page
113      * @param style either <code>GRID</code> or <code>FLAT</code>
114      */

115     protected FieldEditorPreferencePage(String JavaDoc title, int style) {
116         super(title);
117         this.style = style;
118     }
119
120     /**
121      * Creates a new field editor preference page with the given title,
122      * image, and style.
123      *
124      * @param title the title of this preference page
125      * @param image the image for this preference page, or
126      * <code>null</code> if none
127      * @param style either <code>GRID</code> or <code>FLAT</code>
128      */

129     protected FieldEditorPreferencePage(String JavaDoc title, ImageDescriptor image,
130             int style) {
131         super(title, image);
132         this.style = style;
133     }
134
135     /**
136      * Adds the given field editor to this page.
137      *
138      * @param editor the field editor
139      */

140     protected void addField(FieldEditor editor) {
141         if (fields == null) {
142             fields = new ArrayList JavaDoc();
143         }
144         fields.add(editor);
145     }
146
147     /**
148      * Adjust the layout of the field editors so that
149      * they are properly aligned.
150      */

151     protected void adjustGridLayout() {
152         int numColumns = calcNumberOfColumns();
153         ((GridLayout) fieldEditorParent.getLayout()).numColumns = numColumns;
154         if (fields != null) {
155             for (int i = 0; i < fields.size(); i++) {
156                 FieldEditor fieldEditor = (FieldEditor) fields.get(i);
157                 fieldEditor.adjustForNumColumns(numColumns);
158             }
159         }
160     }
161
162     /**
163      * Applys the font to the field editors managed by this page.
164      */

165     protected void applyFont() {
166         if (fields != null) {
167             Iterator JavaDoc e = fields.iterator();
168             while (e.hasNext()) {
169                 FieldEditor pe = (FieldEditor) e.next();
170                 pe.applyFont();
171             }
172         }
173     }
174
175     /**
176      * Calculates the number of columns needed to host all field editors.
177      *
178      * @return the number of columns
179      */

180     private int calcNumberOfColumns() {
181         int result = 0;
182         if (fields != null) {
183             Iterator JavaDoc e = fields.iterator();
184             while (e.hasNext()) {
185                 FieldEditor pe = (FieldEditor) e.next();
186                 result = Math.max(result, pe.getNumberOfControls());
187             }
188         }
189         return result;
190     }
191
192     /**
193      * Recomputes the page's error state by calling <code>isValid</code> for
194      * every field editor.
195      */

196     protected void checkState() {
197         boolean valid = true;
198         invalidFieldEditor = null;
199         // The state can only be set to true if all
200
// field editors contain a valid value. So we must check them all
201
if (fields != null) {
202             int size = fields.size();
203             for (int i = 0; i < size; i++) {
204                 FieldEditor editor = (FieldEditor) fields.get(i);
205                 valid = valid && editor.isValid();
206                 if (!valid) {
207                     invalidFieldEditor = editor;
208                     break;
209                 }
210             }
211         }
212         setValid(valid);
213     }
214
215     /* (non-Javadoc)
216      * Method declared on PreferencePage.
217      */

218     protected Control createContents(Composite parent) {
219         fieldEditorParent = new Composite(parent, SWT.NULL);
220         GridLayout layout = new GridLayout();
221         layout.numColumns = 1;
222         layout.marginHeight = 0;
223         layout.marginWidth = 0;
224         fieldEditorParent.setLayout(layout);
225         fieldEditorParent.setFont(parent.getFont());
226
227         createFieldEditors();
228
229         if (style == GRID) {
230             adjustGridLayout();
231         }
232
233         initialize();
234         checkState();
235         return fieldEditorParent;
236     }
237
238     /**
239      * Creates the page's field editors.
240      * <p>
241      * The default implementation of this framework method
242      * does nothing. Subclass must implement this method to
243      * create the field editors.
244      * </p>
245      * <p>
246      * Subclasses should call <code>getFieldEditorParent</code>
247      * to obtain the parent control for each field editor.
248      * This same parent should not be used for more than
249      * one editor as the parent may change for each field
250      * editor depending on the layout style of the page
251      * </p>
252      */

253     protected abstract void createFieldEditors();
254
255     /**
256      * The field editor preference page implementation of an <code>IDialogPage</code>
257      * method disposes of this page's controls and images.
258      * Subclasses may override to release their own allocated SWT
259      * resources, but must call <code>super.dispose</code>.
260      */

261     public void dispose() {
262         super.dispose();
263         if (fields != null) {
264             Iterator JavaDoc e = fields.iterator();
265             while (e.hasNext()) {
266                 FieldEditor pe = (FieldEditor) e.next();
267                 pe.setPage(null);
268                 pe.setPropertyChangeListener(null);
269                 pe.setPreferenceStore(null);
270             }
271         }
272     }
273
274     /**
275      * Returns a parent composite for a field editor.
276      * <p>
277      * This value must not be cached since a new parent
278      * may be created each time this method called. Thus
279      * this method must be called each time a field editor
280      * is constructed.
281      * </p>
282      *
283      * @return a parent
284      */

285     protected Composite getFieldEditorParent() {
286         if (style == FLAT) {
287             // Create a new parent for each field editor
288
Composite parent = new Composite(fieldEditorParent, SWT.NULL);
289             parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
290             return parent;
291         }
292         // Just return the parent
293
return fieldEditorParent;
294     }
295
296     /**
297      * Initializes all field editors.
298      */

299     protected void initialize() {
300         if (fields != null) {
301             Iterator JavaDoc e = fields.iterator();
302             while (e.hasNext()) {
303                 FieldEditor pe = (FieldEditor) e.next();
304                 pe.setPage(this);
305                 pe.setPropertyChangeListener(this);
306                 pe.setPreferenceStore(getPreferenceStore());
307                 pe.load();
308             }
309         }
310     }
311
312     /**
313      * The field editor preference page implementation of a <code>PreferencePage</code>
314      * method loads all the field editors with their default values.
315      */

316     protected void performDefaults() {
317         if (fields != null) {
318             Iterator JavaDoc e = fields.iterator();
319             while (e.hasNext()) {
320                 FieldEditor pe = (FieldEditor) e.next();
321                 pe.loadDefault();
322             }
323         }
324         // Force a recalculation of my error state.
325
checkState();
326         super.performDefaults();
327     }
328
329     /**
330      * The field editor preference page implementation of this
331      * <code>PreferencePage</code> method saves all field editors by
332      * calling <code>FieldEditor.store</code>. Note that this method
333      * does not save the preference store itself; it just stores the
334      * values back into the preference store.
335      *
336      * @see FieldEditor#store()
337      */

338     public boolean performOk() {
339         if (fields != null) {
340             Iterator JavaDoc e = fields.iterator();
341             while (e.hasNext()) {
342                 FieldEditor pe = (FieldEditor) e.next();
343                 pe.store();
344                 pe.setPresentsDefaultValue(false);
345             }
346         }
347         return true;
348     }
349
350     /**
351      * The field editor preference page implementation of this <code>IPreferencePage</code>
352      * (and <code>IPropertyChangeListener</code>) method intercepts <code>IS_VALID</code>
353      * events but passes other events on to its superclass.
354      */

355     public void propertyChange(PropertyChangeEvent event) {
356
357         if (event.getProperty().equals(FieldEditor.IS_VALID)) {
358             boolean newValue = ((Boolean JavaDoc) event.getNewValue()).booleanValue();
359             // If the new value is true then we must check all field editors.
360
// If it is false, then the page is invalid in any case.
361
if (newValue) {
362                 checkState();
363             } else {
364                 invalidFieldEditor = (FieldEditor) event.getSource();
365                 setValid(newValue);
366             }
367         }
368     }
369
370     /* (non-Javadoc)
371      * Method declared on IDialog.
372      */

373     public void setVisible(boolean visible) {
374         super.setVisible(visible);
375         if (visible && invalidFieldEditor != null) {
376             invalidFieldEditor.setFocus();
377         }
378     }
379 }
380
Popular Tags