1
2
3
4
5
6
7
8
9
10
11
12
13 package org.gscg.common.gui.components.interactivespinner;
14
15 import java.text.DecimalFormat;
16 import java.text.NumberFormat;
17 import java.text.ParseException;
18
19 import javax.swing.JFormattedTextField;
20 import javax.swing.SwingConstants;
21 import javax.swing.text.DefaultFormatterFactory;
22 import javax.swing.text.NumberFormatter;
23
24
25 /***
26 * <p>
27 * (c) copyright 2005 <a href="http://www.simulation.tudelft.nl">Delft
28 * University of Technology </a>, the Netherlands. <br>
29 * See for project information <a
30 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
31 *
32 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
33 * Delft, the Netherlands. All rights reserved.
34 *
35 * See for project information <a href="http://www.simulation.tudelft.nl/">
36 * www.simulation.tudelft.nl </a>.
37 *
38 * The source code and binary code of this software are proprietary information
39 * of Delft University of Technology.
40 *
41 * @author <a
42 * href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
43 * van Houten </a>
44 * @version $Revision: 1.1 $ $Date: 2005/06/16 12:33:56 $
45 * @since 1.1.3
46 */
47 /***
48 * An editor for a <code>JSpinner</code> whose model is a
49 * <code>SpinnerNumberModel</code>. The value of the editor is displayed with
50 * a <code>JFormattedTextField</code> whose format is defined by a
51 * <code>NumberFormatter</code> instance whose <code>minimum</code> and
52 * <code>maximum</code> properties are mapped to the
53 * <code>SpinnerNumberModel</code>.
54 */
55 public class NumberEditor extends DefaultEditor
56 {
57 /***
58 * Construct a <code>JSpinner</code> editor that supports displaying and
59 * editing the value of a <code>SpinnerNumberModel</code> with a
60 * <code>JFormattedTextField</code>.<code>This</code>
61 * <code>NumberEditor</code>
62 * becomes both a <code>ChangeListener</code> on the spinner and a
63 * <code>PropertyChangeListener</code> on the new
64 * <code>JFormattedTextField</code>.
65 *
66 * @param spinner the spinner whose model <code>this</code> editor will
67 * monitor
68 *
69 * @see #getModel
70 * @see #getFormat
71 * @see SpinnerNumberModel
72 */
73 public NumberEditor(final JInteractiveSpinner spinner)
74 {
75 this(spinner, new DecimalFormat());
76 }
77
78 /***
79 * Construct a <code>JSpinner</code> editor that supports displaying and
80 * editing the value of a <code>SpinnerNumberModel</code> with a
81 * <code>JFormattedTextField</code>.<code>This</code>
82 * <code>NumberEditor</code>
83 * becomes both a <code>ChangeListener</code> on the spinner and a
84 * <code>PropertyChangeListener</code> on the new
85 * <code>JFormattedTextField</code>.
86 *
87 * @param spinner the spinner whose model <code>this</code> editor will
88 * monitor
89 * @param decimalFormatPattern the initial pattern for the
90 * <code>DecimalFormat</code> object that's used to display and
91 * parse the value of the text field.
92 * @see SpinnerNumberModel
93 * @see java.text.DecimalFormat
94 */
95 public NumberEditor(final JInteractiveSpinner spinner,
96 final String decimalFormatPattern)
97 {
98 this(spinner, new DecimalFormat(decimalFormatPattern));
99 }
100
101
102 /***
103 * Construct a <code>JSpinner</code> editor that supports displaying and
104 * editing the value of a <code>SpinnerNumberModel</code> with a
105 * <code>JFormattedTextField</code>.<code>This</code>
106 * <code>NumberEditor</code>
107 * becomes both a <code>ChangeListener</code> on the spinner and a
108 * <code>PropertyChangeListener</code> on the new
109 * <code>JFormattedTextField</code>.
110 *
111 * @param spinner the spinner whose model <code>this</code> editor will
112 * monitor
113 * @param format the initial pattern for the <code>DecimalFormat</code>
114 * object that's used to display and parse the value of the text
115 * field.
116 * @see java.text.DecimalFormat
117 */
118 private NumberEditor(final JInteractiveSpinner spinner,
119 final DecimalFormat format)
120 {
121 super(spinner);
122 if (!(spinner.getModel() instanceof SpinnerNumberModel))
123 {
124 throw new IllegalArgumentException("model not a SpinnerNumberModel");
125 }
126
127 SpinnerNumberModel model = (SpinnerNumberModel) spinner.getModel();
128 NumberFormatter formatter = new NumberEditorFormatter(model, format);
129 DefaultFormatterFactory factory = new DefaultFormatterFactory(formatter);
130 JFormattedTextField ftf = getTextField();
131
132 ftf.setFormatterFactory(factory);
133 ftf.setHorizontalAlignment(SwingConstants.RIGHT);
134
135
136
137
138
139
140 try
141 {
142 String maxString = formatter.valueToString(model.getMinimum());
143 String minString = formatter.valueToString(model.getMaximum());
144 ftf.setColumns(Math.max(maxString.length(), minString.length()));
145 } catch (ParseException e)
146 {
147
148 e = null;
149 }
150
151 }
152
153 /***
154 * Returns the <code>java.text.NumberFormat</code> object the
155 * <code>JFormattedTextField</code> uses to parse and format numbers.
156 *
157 * @return the value of
158 * <code>getTextField().getFormatter().getFormat()</code>.
159 * @see java.text.DecimalFormat
160 */
161 public DecimalFormat getFormat()
162 {
163 return (DecimalFormat) ((NumberFormatter) (getTextField()
164 .getFormatter())).getFormat();
165 }
166
167
168 /***
169 * Return our spinner ancestor's <code>SpinnerNumberModel</code>.
170 *
171 * @return <code>getSpinner().getModel()</code>
172 */
173 public SpinnerNumberModel getModel()
174 {
175 return (SpinnerNumberModel) (getSpinner().getModel());
176 }
177
178 /***
179 * This subclass of javax.swing.NumberFormatter maps the minimum/maximum
180 * properties to a SpinnerNumberModel and initializes the valueClass of the
181 * NumberFormatter to match the type of the initial models value.
182 */
183 private static class NumberEditorFormatter extends NumberFormatter
184 {
185 /*** the model */
186 private final SpinnerNumberModel model;
187
188 /***
189
190 * constructs a new NumberEditorFormatter
191 *
192 * @param model the model
193 * @param format the format
194 */
195 public NumberEditorFormatter(final SpinnerNumberModel model,
196 final NumberFormat format)
197 {
198 super(format);
199 this.model = model;
200 setValueClass(model.getValue().getClass());
201 }
202
203 /***
204 * @see javax.swing.text.InternationalFormatter#setMinimum(java.lang.Comparable)
205 */
206 public void setMinimum(final Comparable min)
207 {
208 this.model.setMinimum(min);
209 }
210
211 /***
212 * @see javax.swing.text.InternationalFormatter#getMinimum()
213 */
214 public Comparable getMinimum()
215 {
216 return this.model.getMinimum();
217 }
218
219 /***
220 * @see javax.swing.text.InternationalFormatter#setMaximum(java.lang.Comparable)
221 */
222 public void setMaximum(final Comparable max)
223 {
224 this.model.setMaximum(max);
225 }
226
227 /***
228 * @see javax.swing.text.InternationalFormatter#getMaximum()
229 */
230 public Comparable getMaximum()
231 {
232 return this.model.getMaximum();
233 }
234 }
235 }