KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > synth > SynthSpinnerUI


1 /*
2  * @(#)SynthSpinnerUI.java 1.11 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.plaf.synth;
8
9 import java.awt.*;
10 import java.awt.event.*;
11 import java.text.ParseException JavaDoc;
12
13 import javax.swing.*;
14 import javax.swing.event.*;
15 import javax.swing.plaf.*;
16 import javax.swing.plaf.basic.BasicSpinnerUI JavaDoc;
17 import javax.swing.text.*;
18
19 import java.beans.*;
20 import java.text.*;
21 import java.util.*;
22 import sun.swing.plaf.synth.SynthUI;
23
24 /**
25  * Synth's SpinnerUI.
26  *
27  * @version 1.11, 12/19/03
28  * @author Hans Muller
29  * @author Joshua Outwater
30  */

31 class SynthSpinnerUI extends BasicSpinnerUI JavaDoc implements PropertyChangeListener,
32         SynthUI {
33     private SynthStyle JavaDoc style;
34
35
36     /**
37      * Returns a new instance of SynthSpinnerUI.
38      *
39      * @param c the JSpinner (not used)
40      * @see ComponentUI#createUI
41      * @return a new SynthSpinnerUI object
42      */

43     public static ComponentUI createUI(JComponent c) {
44         return new SynthSpinnerUI JavaDoc();
45     }
46
47     protected void installListeners() {
48         spinner.addPropertyChangeListener(this);
49     }
50
51     /**
52      * Removes the <code>propertyChangeListener</code> added
53      * by installListeners.
54      * <p>
55      * This method is called by <code>uninstallUI</code>.
56      *
57      * @see #installListeners
58      */

59     protected void uninstallListeners() {
60     spinner.removePropertyChangeListener(this);
61     }
62
63     /**
64      * Initialize the <code>JSpinner</code> <code>border</code>,
65      * <code>foreground</code>, and <code>background</code>, properties
66      * based on the corresponding "Spinner.*" properties from defaults table.
67      * The <code>JSpinners</code> layout is set to the value returned by
68      * <code>createLayout</code>. This method is called by <code>installUI</code>.
69      *
70      * @see #uninstallDefaults
71      * @see #installUI
72      * @see #createLayout
73      * @see LookAndFeel#installBorder
74      * @see LookAndFeel#installColors
75      */

76     protected void installDefaults() {
77         LayoutManager layout = spinner.getLayout();
78
79         if (layout == null || layout instanceof UIResource) {
80             spinner.setLayout(createLayout());
81         }
82         updateStyle(spinner);
83     }
84
85
86     private void updateStyle(JSpinner c) {
87         SynthContext JavaDoc context = getContext(c, ENABLED);
88         SynthStyle JavaDoc oldStyle = style;
89         style = SynthLookAndFeel.updateStyle(context, this);
90         if (style != oldStyle) {
91             if (oldStyle != null) {
92                 // Only call installKeyboardActions as uninstall is not
93
// public.
94
installKeyboardActions();
95             }
96         }
97         context.dispose();
98     }
99
100
101     /**
102      * Sets the <code>JSpinner's</code> layout manager to null. This
103      * method is called by <code>uninstallUI</code>.
104      *
105      * @see #installDefaults
106      * @see #uninstallUI
107      */

108     protected void uninstallDefaults() {
109         if (spinner.getLayout() instanceof UIResource) {
110             spinner.setLayout(null);
111         }
112
113         SynthContext JavaDoc context = getContext(spinner, ENABLED);
114
115         style.uninstallDefaults(context);
116         context.dispose();
117         style = null;
118     }
119
120
121     protected LayoutManager createLayout() {
122         return new SpinnerLayout();
123     }
124
125
126     // Not used since we overload install/uninstallListeners.
127
protected PropertyChangeListener createPropertyChangeListener() {
128     return this;
129     }
130
131
132     /**
133      * Create a component that will replace the spinner models value
134      * with the object returned by <code>spinner.getPreviousValue</code>.
135      * By default the <code>previousButton</code> is a JButton
136      * who's <code>ActionListener</code> updates it's <code>JSpinner</code>
137      * ancestors model. If a previousButton isn't needed (in a subclass)
138      * then override this method to return null.
139      *
140      * @return a component that will replace the spinners model with the
141      * next value in the sequence, or null
142      * @see #installUI
143      * @see #createNextButton
144      */

145     protected Component createPreviousButton() {
146     JButton b = new SynthArrowButton JavaDoc(SwingConstants.SOUTH);
147         b.setName("Spinner.previousButton");
148         installPreviousButtonListeners(b);
149     return b;
150     }
151
152
153     /**
154      * Create a component that will replace the spinner models value
155      * with the object returned by <code>spinner.getNextValue</code>.
156      * By default the <code>nextButton</code> is a JButton
157      * who's <code>ActionListener</code> updates it's <code>JSpinner</code>
158      * ancestors model. If a nextButton isn't needed (in a subclass)
159      * then override this method to return null.
160      *
161      * @return a component that will replace the spinners model with the
162      * next value in the sequence, or null
163      * @see #installUI
164      * @see #createPreviousButton
165      */

166     protected Component createNextButton() {
167     JButton b = new SynthArrowButton JavaDoc(SwingConstants.NORTH);
168         b.setName("Spinner.nextButton");
169         installNextButtonListeners(b);
170     return b;
171     }
172
173
174     /**
175      * This method is called by installUI to get the editor component
176      * of the <code>JSpinner</code>. By default it just returns
177      * <code>JSpinner.getEditor()</code>. Subclasses can override
178      * <code>createEditor</code> to return a component that contains
179      * the spinner's editor or null, if they're going to handle adding
180      * the editor to the <code>JSpinner</code> in an
181      * <code>installUI</code> override.
182      * <p>
183      * Typically this method would be overridden to wrap the editor
184      * with a container with a custom border, since one can't assume
185      * that the editors border can be set directly.
186      * <p>
187      * The <code>replaceEditor</code> method is called when the spinners
188      * editor is changed with <code>JSpinner.setEditor</code>. If you've
189      * overriden this method, then you'll probably want to override
190      * <code>replaceEditor</code> as well.
191      *
192      * @return the JSpinners editor JComponent, spinner.getEditor() by default
193      * @see #installUI
194      * @see #replaceEditor
195      * @see JSpinner#getEditor
196      */

197     protected JComponent createEditor() {
198         JComponent editor = spinner.getEditor();
199         editor.setName("Spinner.editor");
200     return editor;
201     }
202
203
204     /**
205      * Called by the <code>PropertyChangeListener</code> when the
206      * <code>JSpinner</code> editor property changes. It's the responsibility
207      * of this method to remove the old editor and add the new one. By
208      * default this operation is just:
209      * <pre>
210      * spinner.remove(oldEditor);
211      * spinner.add(newEditor, "Editor");
212      * </pre>
213      * The implementation of <code>replaceEditor</code> should be coordinated
214      * with the <code>createEditor</code> method.
215      *
216      * @see #createEditor
217      * @see #createPropertyChangeListener
218      */

219     protected void replaceEditor(JComponent oldEditor, JComponent newEditor) {
220     spinner.remove(oldEditor);
221     spinner.add(newEditor, "Editor");
222     }
223
224
225     /**
226      * Updates the enabled state of the children Components based on the
227      * enabled state of the <code>JSpinner</code>.
228      */

229     private void updateEnabledState() {
230         updateEnabledState(spinner, spinner.isEnabled());
231     }
232
233
234     /**
235      * Recursively updates the enabled state of the child
236      * <code>Component</code>s of <code>c</code>.
237      */

238     private void updateEnabledState(Container c, boolean enabled) {
239         for (int counter = c.getComponentCount() - 1; counter >= 0;counter--) {
240             Component child = c.getComponent(counter);
241
242             child.setEnabled(enabled);
243             if (child instanceof Container) {
244                 updateEnabledState((Container)child, enabled);
245             }
246         }
247     }
248
249
250     public SynthContext JavaDoc getContext(JComponent c) {
251         return getContext(c, getComponentState(c));
252     }
253
254     private SynthContext JavaDoc getContext(JComponent c, int state) {
255         return SynthContext.getContext(SynthContext JavaDoc.class, c,
256                     SynthLookAndFeel.getRegion(c), style, state);
257     }
258
259
260     private Region JavaDoc getRegion(JComponent c) {
261         return SynthLookAndFeel.getRegion(c);
262     }
263
264
265     private int getComponentState(JComponent c) {
266         return SynthLookAndFeel.getComponentState(c);
267     }
268
269
270     public void update(Graphics g, JComponent c) {
271         SynthContext JavaDoc context = getContext(c);
272
273         SynthLookAndFeel.update(context, g);
274         context.getPainter().paintSpinnerBackground(context,
275                           g, 0, 0, c.getWidth(), c.getHeight());
276         paint(context, g);
277         context.dispose();
278     }
279
280
281     public void paint(Graphics g, JComponent c) {
282         SynthContext JavaDoc context = getContext(c);
283
284         paint(context, g);
285         context.dispose();
286     }
287
288
289     protected void paint(SynthContext JavaDoc context, Graphics g) {
290     }
291
292     public void paintBorder(SynthContext JavaDoc context, Graphics g, int x,
293                             int y, int w, int h) {
294         context.getPainter().paintSpinnerBorder(context, g, x, y, w, h);
295     }
296
297     /**
298      * A simple layout manager for the editor and the next/previous buttons.
299      * See the SynthSpinnerUI javadoc for more information about exactly
300      * how the components are arranged.
301      */

302     private static class SpinnerLayout implements LayoutManager, UIResource
303     {
304     private Component nextButton = null;
305     private Component previousButton = null;
306     private Component editor = null;
307
308     public void addLayoutComponent(String JavaDoc name, Component c) {
309         if ("Next".equals(name)) {
310         nextButton = c;
311         }
312         else if ("Previous".equals(name)) {
313         previousButton = c;
314         }
315         else if ("Editor".equals(name)) {
316         editor = c;
317         }
318     }
319
320     public void removeLayoutComponent(Component c) {
321         if (c == nextButton) {
322         c = null;
323         }
324         else if (c == previousButton) {
325         previousButton = null;
326         }
327         else if (c == editor) {
328         editor = null;
329         }
330     }
331
332     private Dimension preferredSize(Component c) {
333         return (c == null) ? new Dimension(0, 0) : c.getPreferredSize();
334     }
335
336     public Dimension preferredLayoutSize(Container parent) {
337         Dimension nextD = preferredSize(nextButton);
338         Dimension previousD = preferredSize(previousButton);
339         Dimension editorD = preferredSize(editor);
340
341         /* Force the editors height to be a multiple of 2
342          */

343         editorD.height = ((editorD.height + 1) / 2) * 2;
344
345         Dimension size = new Dimension(editorD.width, editorD.height);
346         size.width += Math.max(nextD.width, previousD.width);
347         Insets insets = parent.getInsets();
348         size.width += insets.left + insets.right;
349         size.height += insets.top + insets.bottom;
350         return size;
351     }
352
353     public Dimension minimumLayoutSize(Container parent) {
354         return preferredLayoutSize(parent);
355     }
356
357     private void setBounds(Component c, int x, int y, int width, int height) {
358         if (c != null) {
359         c.setBounds(x, y, width, height);
360         }
361     }
362
363     public void layoutContainer(Container parent) {
364         Insets insets = parent.getInsets();
365         int availWidth = parent.getWidth() - (insets.left + insets.right);
366         int availHeight = parent.getHeight() - (insets.top + insets.bottom);
367         Dimension nextD = preferredSize(nextButton);
368         Dimension previousD = preferredSize(previousButton);
369         int nextHeight = availHeight / 2;
370         int previousHeight = availHeight - nextHeight;
371         int buttonsWidth = Math.max(nextD.width, previousD.width);
372         int editorWidth = availWidth - buttonsWidth;
373
374         /* Deal with the spinners componentOrientation property.
375          */

376         int editorX, buttonsX;
377         if (parent.getComponentOrientation().isLeftToRight()) {
378         editorX = insets.left;
379         buttonsX = editorX + editorWidth;
380         }
381         else {
382         buttonsX = insets.left;
383         editorX = buttonsX + buttonsWidth;
384         }
385
386         int previousY = insets.top + nextHeight;
387         setBounds(editor, editorX, insets.top, editorWidth, availHeight);
388         setBounds(nextButton, buttonsX, insets.top, buttonsWidth, nextHeight);
389         setBounds(previousButton, buttonsX, previousY, buttonsWidth, previousHeight);
390     }
391     }
392
393
394     public void propertyChange(PropertyChangeEvent e) {
395         String JavaDoc propertyName = e.getPropertyName();
396         JSpinner spinner = (JSpinner)(e.getSource());
397         SpinnerUI JavaDoc spinnerUI = spinner.getUI();
398     
399         if (spinnerUI instanceof SynthSpinnerUI JavaDoc) {
400             SynthSpinnerUI JavaDoc ui = (SynthSpinnerUI JavaDoc)spinnerUI;
401     
402             if (SynthLookAndFeel.shouldUpdateStyle(e)) {
403                 ui.updateStyle(spinner);
404             }
405             if ("editor".equals(propertyName)) {
406                 JComponent oldEditor = (JComponent)e.getOldValue();
407                 JComponent newEditor = (JComponent)e.getNewValue();
408                 ui.replaceEditor(oldEditor, newEditor);
409                 ui.updateEnabledState();
410             }
411             else if ("enabled".equals(propertyName)) {
412                 ui.updateEnabledState();
413             }
414         }
415     }
416 }
417
Popular Tags