View Javadoc

1   // LabelledScaleFieldEditor.java, created Aug 14, 2004 7:42:14 PM by joewhaley
2   // Copyright (C) 2004 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the CPL; see LICENSE.txt for details.
4   package edu.stanford.suif.keepresident;
5   
6   import org.eclipse.jface.preference.FieldEditor;
7   import org.eclipse.swt.SWT;
8   import org.eclipse.swt.events.DisposeEvent;
9   import org.eclipse.swt.events.DisposeListener;
10  import org.eclipse.swt.events.SelectionAdapter;
11  import org.eclipse.swt.events.SelectionEvent;
12  import org.eclipse.swt.layout.GridData;
13  import org.eclipse.swt.widgets.Composite;
14  import org.eclipse.swt.widgets.Control;
15  import org.eclipse.swt.widgets.Label;
16  import org.eclipse.swt.widgets.Scale;
17  
18  /***
19   * LabelledScaleFieldEditor
20   * 
21   * @author John Whaley
22   * @version $Id: LabelledScaleFieldEditor.java,v 1.5 2004/08/18 07:28:32 jwhaley Exp $
23   */
24  public class LabelledScaleFieldEditor extends FieldEditor {
25      /***
26       * Value that will feed Scale.setIncrement(int).
27       */
28      private int incrementValue;
29      /***
30       * Value that will feed Scale.setMaximum(int).
31       */
32      private int maxValue;
33      /***
34       * Value that will feed Scale.setMinimum(int).
35       */
36      private int minValue;
37      /***
38       * Old integer value.
39       */
40      private int oldValue;
41      /***
42       * Value that will feed Scale.setPageIncrement(int).
43       */
44      private int pageIncrementValue;
45      /***
46       * The scale, or <code>null</code> if none.
47       */
48      protected Scale scale;
49      protected Label myLabel;
50  
51      /***
52       * Creates a scale field editor.
53       * 
54       * @param name
55       *            the name of the preference this field editor works on
56       * @param labelText
57       *            the label text of the field editor
58       * @param parent
59       *            the parent of the field editor's control
60       */
61      public LabelledScaleFieldEditor(String name, String labelText, Composite parent) {
62          super(name, labelText, parent);
63          setDefaultValues();
64      }
65  
66      /***
67       * Creates a scale field editor with particular scale values.
68       * 
69       * @param name
70       *            the name of the preference this field editor works on
71       * @param labelText
72       *            the label text of the field editor
73       * @param parent
74       *            the parent of the field editor's control
75       * @param min
76       *            the value used for Scale.setMinimum(int).
77       * @param max
78       *            the value used for Scale.setMaximum(int).
79       * @param increment
80       *            the value used for Scale.setIncrement(int).
81       * @param pageIncrement
82       *            the value used for Scale.setPageIncrement(int).
83       */
84      public LabelledScaleFieldEditor(String name, String labelText, Composite parent, int min, int max,
85          int increment, int pageIncrement) {
86          super(name, labelText, parent);
87          setValues(min, max, increment, pageIncrement);
88      }
89  
90      /*
91       * (non-Javadoc)
92       * 
93       * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int)
94       */
95      protected void adjustForNumColumns(int numColumns) {
96          ((GridData) scale.getLayoutData()).horizontalSpan = numColumns - 2;
97          ((GridData) myLabel.getLayoutData()).horizontalSpan = 1;
98      }
99  
100     /*
101      * (non-Javadoc)
102      * 
103      * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite,
104      *      int)
105      */
106     protected void doFillIntoGrid(Composite parent, int numColumns) {
107         Control control = getLabelControl(parent);
108         GridData gd = new GridData();
109         control.setLayoutData(gd);
110         
111         scale = getScaleControl(parent);
112         gd = new GridData(GridData.FILL_HORIZONTAL);
113         gd.verticalAlignment = GridData.FILL;
114         gd.horizontalSpan = numColumns - 2;
115         //gd.grabExcessHorizontalSpace = true;
116         scale.setLayoutData(gd);
117         
118         myLabel = getMyLabelControl(parent);
119         gd = new GridData();
120         gd.horizontalSpan = 1;
121         myLabel.setLayoutData(gd);
122         
123         updateScale();
124     }
125 
126     /*
127      * (non-Javadoc)
128      * 
129      * @see org.eclipse.jface.preference.FieldEditor#doLoad()
130      */
131     protected void doLoad() {
132         if (scale != null) {
133             int value = getPreferenceStore().getInt(getPreferenceName());
134             value = Math.max(value, minValue);
135             value = Math.min(value, maxValue);
136             scale.setSelection(value);
137             myLabel.setText(decorateLabel(value));
138             oldValue = value;
139         }
140     }
141 
142     /*
143      * (non-Javadoc)
144      * 
145      * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault()
146      */
147     protected void doLoadDefault() {
148         if (scale != null) {
149             int value = getPreferenceStore().getDefaultInt(getPreferenceName());
150             value = Math.max(value, minValue);
151             value = Math.min(value, maxValue);
152             scale.setSelection(value);
153             myLabel.setText(decorateLabel(value));
154         }
155         valueChanged();
156     }
157 
158     /*
159      * (non-Javadoc)
160      * 
161      * @see org.eclipse.jface.preference.FieldEditor#doStore()
162      */
163     protected void doStore() {
164         getPreferenceStore().setValue(getPreferenceName(), scale.getSelection());
165     }
166 
167     /***
168      * Returns the value that will be used for Scale.setIncrement(int).
169      * 
170      * @return the value.
171      * @see org.eclipse.swt.widgets.Scale#setIncrement(int)
172      */
173     public int getIncrement() {
174         return incrementValue;
175     }
176 
177     /***
178      * Returns the value that will be used for Scale.setMaximum(int).
179      * 
180      * @return the value.
181      * @see org.eclipse.swt.widgets.Scale#setMaximum(int)
182      */
183     public int getMaximum() {
184         return maxValue;
185     }
186 
187     /***
188      * Returns the value that will be used for Scale.setMinimum(int).
189      * 
190      * @return the value.
191      * @see org.eclipse.swt.widgets.Scale#setMinimum(int)
192      */
193     public int getMinimum() {
194         return minValue;
195     }
196 
197     /*
198      * (non-Javadoc)
199      * 
200      * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls()
201      */
202     public int getNumberOfControls() {
203         return 3;
204     }
205 
206     /***
207      * Returns the value that will be used for Scale.setPageIncrement(int).
208      * 
209      * @return the value.
210      * @see org.eclipse.swt.widgets.Scale#setPageIncrement(int)
211      */
212     public int getPageIncrement() {
213         return pageIncrementValue;
214     }
215 
216     /***
217      * Returns this field editor's scale control.
218      * 
219      * @return the scale control, or <code>null</code> if no scale field is
220      *         created yet
221      */
222     public Scale getScaleControl() {
223         return scale;
224     }
225 
226     /***
227      * Returns this field editor's scale control. The control is created if it
228      * does not yet exist.
229      * 
230      * @param parent
231      *            the parent
232      * @return the scale control
233      */
234     private Scale getScaleControl(Composite parent) {
235         if (scale == null) {
236             scale = new Scale(parent, SWT.HORIZONTAL);
237             scale.setFont(parent.getFont());
238             scale.addSelectionListener(new SelectionAdapter() {
239                 public void widgetSelected(SelectionEvent event) {
240                     valueChanged();
241                 }
242             });
243             scale.addDisposeListener(new DisposeListener() {
244                 public void widgetDisposed(DisposeEvent event) {
245                     scale = null;
246                 }
247             });
248         } else {
249             checkParent(scale, parent);
250         }
251         return scale;
252     }
253 
254     private Label getMyLabelControl(Composite parent) {
255         if (myLabel == null) {
256             myLabel = new Label(parent, SWT.HORIZONTAL);
257             myLabel.setFont(parent.getFont());
258             myLabel.addDisposeListener(new DisposeListener() {
259                 public void widgetDisposed(DisposeEvent event) {
260                     myLabel = null;
261                 }
262             });
263         } else {
264             checkParent(myLabel, parent);
265         }
266         return myLabel;
267     }
268     
269     /***
270      * Set default values for the various scale fields. These defaults are: <br>
271      * <ul>
272      * <li>Minimum = 0
273      * <li>Maximim = 10
274      * <li>Increment = 1
275      * <li>Page Increment = 1
276      * </ul>
277      */
278     private void setDefaultValues() {
279         setValues(0, 10, 1, 1);
280     }
281 
282     /*
283      * (non-Javadoc)
284      * 
285      * @see org.eclipse.jface.preference.FieldEditor#setFocus()
286      */
287     public void setFocus() {
288         if (scale != null && !scale.isDisposed()) {
289             scale.setFocus();
290         }
291     }
292 
293     /***
294      * Set the value to be used for Scale.setIncrement(int) and update the
295      * scale.
296      * 
297      * @param increment
298      *            a value greater than 0.
299      * @see org.eclipse.swt.widgets.Scale#setIncrement(int)
300      */
301     public void setIncrement(int increment) {
302         this.incrementValue = increment;
303         updateScale();
304     }
305 
306     /***
307      * Set the value to be used for Scale.setMaximum(int) and update the scale.
308      * 
309      * @param max
310      *            a value greater than 0.
311      * @see org.eclipse.swt.widgets.Scale#setMaximum(int)
312      */
313     public void setMaximum(int max) {
314         this.maxValue = max;
315         updateScale();
316     }
317 
318     /***
319      * Set the value to be used for Scale.setMinumum(int) and update the scale.
320      * 
321      * @param min
322      *            a value greater than 0.
323      * @see org.eclipse.swt.widgets.Scale#setMinimum(int)
324      */
325     public void setMinimum(int min) {
326         this.minValue = min;
327         updateScale();
328     }
329 
330     /***
331      * Set the value to be used for Scale.setPageIncrement(int) and update the
332      * scale.
333      * 
334      * @param pageIncrement
335      *            a value greater than 0.
336      * @see org.eclipse.swt.widgets.Scale#setPageIncrement(int)
337      */
338     public void setPageIncrement(int pageIncrement) {
339         this.pageIncrementValue = pageIncrement;
340         updateScale();
341     }
342 
343     /***
344      * Set all Scale values.
345      * 
346      * @param min
347      *            the value used for Scale.setMinimum(int).
348      * @param max
349      *            the value used for Scale.setMaximum(int).
350      * @param increment
351      *            the value used for Scale.setIncrement(int).
352      * @param pageIncrement
353      *            the value used for Scale.setPageIncrement(int).
354      */
355     private void setValues(int min, int max, int increment, int pageIncrement) {
356         this.incrementValue = increment;
357         this.maxValue = max;
358         this.minValue = min;
359         this.pageIncrementValue = pageIncrement;
360         updateScale();
361     }
362 
363     /***
364      * Update the scale particulars with set values.
365      */
366     private void updateScale() {
367         if (scale != null && !scale.isDisposed()) {
368             scale.setMinimum(getMinimum());
369             scale.setMaximum(getMaximum());
370             scale.setMinimum(getMinimum());
371             scale.setIncrement(getIncrement());
372             scale.setPageIncrement(getPageIncrement());
373         }
374     }
375 
376     /***
377      * Informs this field editor's listener, if it has one, about a change to
378      * the value (<code>VALUE</code> property) provided that the old and new
379      * values are different.
380      * <p>
381      * This hook is <em>not</em> called when the scale is initialized (or
382      * reset to the default value) from the preference store.
383      * </p>
384      */
385     protected void valueChanged() {
386         setPresentsDefaultValue(false);
387         int newValue = scale.getSelection();
388         if (newValue != oldValue) {
389             fireStateChanged(IS_VALID, false, true);
390             fireValueChanged(VALUE, new Integer(oldValue), new Integer(newValue));
391             myLabel.setText(decorateLabel(newValue));
392             oldValue = newValue;
393         }
394     }
395     
396     /***
397      * Converts the given number to a readable form.
398      * Patch due to Erich Haltenwanger.
399      */
400     private String decorateLabel(int size) {
401         final int kb_min = 1024;
402         final int kb_max = 1024 * 1024;
403         final int mb_min = kb_max;
404         final int mb_max = 1024 * 1024 * 1024;
405         int newValueDisplayed;
406         String appendix;
407         if (size < kb_min) {
408             appendix = " Byte";
409             newValueDisplayed = size;
410         } else if (size >= kb_min && size < kb_max) {
411             appendix = " KB";
412             newValueDisplayed = size / kb_min;
413         } else if (size >= mb_min && size < mb_max) {
414             appendix = " MB";
415             newValueDisplayed = size / mb_min;
416         } else {
417             newValueDisplayed = size;
418             appendix = " ???";
419         }
420         StringBuffer buffy = new StringBuffer();
421         buffy.append(newValueDisplayed);
422         buffy.append(appendix);
423         pad(buffy, PADDING);
424         return buffy.toString();
425     }
426     
427     public static final int PADDING = 10;
428     
429     private void pad(StringBuffer sb, int k) {
430         while (sb.length() < k) {
431             sb.append(' ');
432         }
433     }
434 }