KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > looks > plastic > PlasticSpinnerUI


1 /*
2  * Copyright (c) 2001-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.looks.plastic;
32
33 import java.awt.Component JavaDoc;
34 import java.awt.Insets JavaDoc;
35 import java.awt.LayoutManager JavaDoc;
36
37 import javax.swing.JComponent JavaDoc;
38 import javax.swing.JSpinner JavaDoc;
39 import javax.swing.SwingConstants JavaDoc;
40 import javax.swing.UIManager JavaDoc;
41 import javax.swing.border.Border JavaDoc;
42 import javax.swing.plaf.BorderUIResource JavaDoc;
43 import javax.swing.plaf.ComponentUI JavaDoc;
44 import javax.swing.plaf.basic.BasicBorders JavaDoc;
45 import javax.swing.plaf.basic.BasicSpinnerUI JavaDoc;
46
47 import com.jgoodies.looks.common.ExtBasicArrowButtonHandler;
48 import com.jgoodies.looks.common.ExtBasicSpinnerLayout;
49
50
51 /**
52  * The JGoodies Plastic Look&amp;Feel implementation of <code>SpinnerUI</code>.
53  * Configures the default editor to adjust font baselines and component
54  * bounds. Also, changes the border of the buttons and the size of the arrows.
55  *
56  * @author Karsten Lentzsch
57  * @version $Revision: 1.4 $
58  */

59 public class PlasticSpinnerUI extends BasicSpinnerUI JavaDoc {
60     
61     private static final Border JavaDoc MARGIN_BORDER =
62         new BorderUIResource JavaDoc(new BasicBorders.MarginBorder JavaDoc());
63     
64     
65     public static ComponentUI JavaDoc createUI(JComponent JavaDoc b) {
66         return new PlasticSpinnerUI();
67     }
68
69
70     /**
71      * The mouse/action listeners that are added to the spinner's
72      * arrow buttons. These listeners are shared by all
73      * spinner arrow buttons.
74      *
75      * @see #createNextButton
76      * @see #createPreviousButton
77      */

78     private static final ExtBasicArrowButtonHandler nextButtonHandler
79                                 = new ExtBasicArrowButtonHandler("increment", true);
80     private static final ExtBasicArrowButtonHandler previousButtonHandler
81                                 = new ExtBasicArrowButtonHandler("decrement", false);
82
83
84     /**
85      * Create a component that will replace the spinner models value
86      * with the object returned by <code>spinner.getPreviousValue</code>.
87      * By default the <code>previousButton</code> is a JButton
88      * who's <code>ActionListener</code> updates it's <code>JSpinner</code>
89      * ancestors model. If a previousButton isn't needed (in a subclass)
90      * then override this method to return null.
91      *
92      * @return a component that will replace the spinners model with the
93      * next value in the sequence, or null
94      * @see #installUI
95      * @see #createNextButton
96      */

97     protected Component JavaDoc createPreviousButton() {
98         return new SpinnerArrowButton(SwingConstants.SOUTH, previousButtonHandler);
99     }
100
101
102     /**
103      * Create a component that will replace the spinner models value
104      * with the object returned by <code>spinner.getNextValue</code>.
105      * By default the <code>nextButton</code> is a JButton
106      * who's <code>ActionListener</code> updates it's <code>JSpinner</code>
107      * ancestors model. If a nextButton isn't needed (in a subclass)
108      * then override this method to return null.
109      *
110      * @return a component that will replace the spinners model with the
111      * next value in the sequence, or null
112      * @see #installUI
113      * @see #createPreviousButton
114      */

115     protected Component JavaDoc createNextButton() {
116         return new SpinnerArrowButton(SwingConstants.NORTH, nextButtonHandler);
117     }
118
119
120     /**
121      * Create a <code>LayoutManager</code> that manages the <code>editor</code>,
122      * <code>nextButton</code>, and <code>previousButton</code> children
123      * of the JSpinner. These three children must be added with a constraint
124      * that identifies their role: "Editor", "Next", and "Previous". The
125      * default layout manager can handle the absence of any of these children.
126      *
127      * @return a LayoutManager for the editor, next button, and previous
128      * button.
129      * @see #createNextButton
130      * @see #createPreviousButton
131      * @see #createEditor
132      */

133     protected LayoutManager JavaDoc createLayout() {
134         return new ExtBasicSpinnerLayout();
135     }
136     
137     
138     /**
139      * This method is called by installUI to get the editor component
140      * of the <code>JSpinner</code>. By default it just returns
141      * <code>JSpinner.getEditor()</code>. Subclasses can override
142      * <code>createEditor</code> to return a component that contains
143      * the spinner's editor or null, if they're going to handle adding
144      * the editor to the <code>JSpinner</code> in an
145      * <code>installUI</code> override.
146      * <p>
147      * Typically this method would be overridden to wrap the editor
148      * with a container with a custom border, since one can't assume
149      * that the editors border can be set directly.
150      * <p>
151      * The <code>replaceEditor</code> method is called when the spinners
152      * editor is changed with <code>JSpinner.setEditor</code>. If you've
153      * overriden this method, then you'll probably want to override
154      * <code>replaceEditor</code> as well.
155      *
156      * @return the JSpinners editor JComponent, spinner.getEditor() by default
157      * @see #installUI
158      * @see #replaceEditor
159      * @see JSpinner#getEditor
160      */

161     protected JComponent JavaDoc createEditor() {
162         JComponent JavaDoc editor = spinner.getEditor();
163         configureEditor(editor);
164         return editor;
165     }
166     
167     /**
168      * Called by the <code>PropertyChangeListener</code> when the
169      * <code>JSpinner</code> editor property changes. It's the responsibility
170      * of this method to remove the old editor and add the new one. By
171      * default this operation is just:
172      * <pre>
173      * spinner.remove(oldEditor);
174      * spinner.add(newEditor, "Editor");
175      * </pre>
176      * The implementation of <code>replaceEditor</code> should be coordinated
177      * with the <code>createEditor</code> method.
178      *
179      * @see #createEditor
180      * @see #createPropertyChangeListener
181      */

182     protected void replaceEditor(JComponent JavaDoc oldEditor, JComponent JavaDoc newEditor) {
183         spinner.remove(oldEditor);
184         configureEditor(newEditor);
185         spinner.add(newEditor, "Editor");
186     }
187     
188     
189     /**
190      * Removes an obsolete Border from Default editors.
191      */

192     private void configureEditor(JComponent JavaDoc editor) {
193         if ((editor instanceof JSpinner.DefaultEditor JavaDoc)) {
194             JSpinner.DefaultEditor JavaDoc defaultEditor = (JSpinner.DefaultEditor JavaDoc) editor;
195             defaultEditor.getTextField().getUI();
196             defaultEditor.getTextField().setBorder(MARGIN_BORDER);
197             Insets JavaDoc insets = UIManager.getInsets("Spinner.defaultEditorInsets");
198             defaultEditor.getTextField().setMargin(insets);
199         }
200     }
201
202     /**
203      * It differs from its superclass in that it uses the same formula as JDK
204      * to calculate the arrow height.
205      */

206     private static class SpinnerArrowButton extends PlasticArrowButton {
207         private SpinnerArrowButton(int direction,
208                 ExtBasicArrowButtonHandler handler) {
209             super(direction, UIManager.getInt("ScrollBar.width"), true);
210             addActionListener(handler);
211             addMouseListener(handler);
212         }
213
214         protected int calculateArrowHeight(int height, int width) {
215             int arrowHeight = Math.min((height - 4) / 3, (width - 4) / 3);
216             return Math.max(arrowHeight, 3);
217         }
218         
219         protected int calculateArrowOffset() {
220             return 1;
221         }
222         
223         protected boolean isPaintingNorthBottom() {
224             return true;
225         }
226         
227    }
228
229 }
Popular Tags