Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.ui / src / main / java / org / gvsig / gui / beans / swing / JNumberSpinner.java @ 42079

History | View | Annotate | Download (12.4 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.gui.beans.swing;
24

    
25
import java.awt.event.ActionEvent;
26
import java.awt.event.ActionListener;
27
import java.text.DecimalFormat;
28
import java.util.ArrayList;
29
import java.util.List;
30

    
31
import javax.swing.JFormattedTextField;
32
import javax.swing.JSpinner;
33
import javax.swing.SpinnerNumberModel;
34
import javax.swing.text.NumberFormatter;
35

    
36
import org.apache.commons.lang3.StringUtils;
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

    
40
public class JNumberSpinner extends JSpinner {
41

    
42
    /**
43
     *
44
     */
45
    private static final long serialVersionUID = 8614785196224519553L;
46

    
47
    private static final Logger logger = LoggerFactory.getLogger(JNumberSpinner.class);
48

    
49
    private boolean fireChanges;
50
    private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
51

    
52
    private final int defaultColumns = 10;
53

    
54
    public JNumberSpinner() {
55
        super(new SpinnerNumberModel(0.0, Double.NEGATIVE_INFINITY, Double.MAX_VALUE, 1.0));
56
        init(defaultColumns,0);
57
    }
58

    
59
    public JNumberSpinner(int currentValue) {
60
        super(new SpinnerNumberModel(currentValue, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
61
        init(defaultColumns,0);
62
    }
63

    
64
    public JNumberSpinner(int currentValue, int columns) {
65
        super(new SpinnerNumberModel(currentValue, Integer.MIN_VALUE, Integer.MAX_VALUE, 1));
66
        init(columns,0);
67
    }
68

    
69
    public JNumberSpinner(int currentValue, int columns, int minValue, int maxValue, int step) {
70
        super(new SpinnerNumberModel(currentValue, minValue, maxValue, step));
71
        init(columns,0);
72
    }
73

    
74
    /*
75
     * @deprecated use {@link #JNumberSpinner(int, int, int, int, int)} instead.
76
    */
77
   @Deprecated
78
   public JNumberSpinner(String currentValue, int columns, int minValue, int maxValue, int step) {
79
        super(new SpinnerNumberModel());
80

    
81
        Number value;
82

    
83
        if (StringUtils.isBlank(currentValue)) {
84
            value = null;
85
        } else {
86
            try {
87
                value = new Integer(Integer.parseInt(currentValue));
88
            } catch (Exception ex) {
89
                value = null;
90
            }
91
        }
92
        init(
93
                value == null ? 0 : value,
94
                columns,
95
                new Integer(minValue),
96
                new Integer(maxValue),
97
                new Integer(step),
98
                0
99
        );
100
        if (value == null) {
101
            JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
102
            JFormattedTextField textField = editor.getTextField();
103
            textField.setText("");
104
        }
105
    }
106

    
107
    public JNumberSpinner(int currentValue, int columns, int minValue, int maxValue, int step, int decimals) {
108
        super(new SpinnerNumberModel(currentValue, minValue, maxValue, step));
109
        init(
110
                columns,
111
                decimals
112
        );
113
    }
114

    
115
    public JNumberSpinner(double currentValue) {
116
        super(new SpinnerNumberModel(currentValue, Double.NEGATIVE_INFINITY, Double.MAX_VALUE, 1.0));
117
        init(defaultColumns,4);
118
    }
119

    
120
    /*
121
     * @deprecated use {@link #JNumberSpinner(double, int, double, double, double)} instead.
122
     */
123
    @Deprecated
124
    public JNumberSpinner(String currentValue, int columns, double minValue, double maxValue, double step) {
125
        this(
126
                currentValue,
127
                columns,
128
                minValue,
129
                maxValue,
130
                step,
131
                0
132
        );
133
    }
134

    
135
    /*
136
     * @deprecated use {@link #JNumberSpinner(double currentValue, int columns,
137
     * double minValue, double maxValue, double step, int decimals)} instead.
138
     */
139
    @Deprecated
140
    public JNumberSpinner(String currentValue, int columns, double minValue, double maxValue, double step, int decimals) {
141
        super(new SpinnerNumberModel());
142

    
143
        Number value;
144

    
145
        if (StringUtils.isBlank(currentValue)) {
146
            value = null;
147
        } else {
148
            try {
149
                value = new Double(Double.parseDouble(currentValue));
150
            } catch (Exception ex) {
151
                value = null;
152
            }
153
        }
154
        init(
155
                value == null ? 0.0 : value,
156
                columns,
157
                new Double(minValue),
158
                new Double(maxValue),
159
                new Double(step),
160
                decimals
161
        );
162
        if (value == null) {
163
            JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
164
            JFormattedTextField textField = editor.getTextField();
165
            textField.setText("");
166
        }
167
    }
168

    
169
    public JNumberSpinner(double currentValue, int columns, double minValue, double maxValue, double step) {
170
        super(new SpinnerNumberModel(currentValue, minValue, maxValue, step));
171
        init(columns,4);
172
    }
173

    
174
    public JNumberSpinner(double currentValue, int columns, double minValue, double maxValue, double step, int decimals) {
175
        super(new SpinnerNumberModel(currentValue, minValue, maxValue, step));
176
        init(columns,decimals);
177
    }
178

    
179
    private void init(int columns,int decimals) {
180
        JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
181
        JFormattedTextField textField = editor.getTextField();
182
        NumberFormatter formatter = (NumberFormatter) textField.getFormatter();
183
        DecimalFormat format = editor.getFormat();
184

    
185
        if (columns > 0) {
186
            textField.setColumns(columns);
187
        }
188

    
189
        format.setMinimumFractionDigits(decimals);
190
        formatter.setAllowsInvalid(true);
191

    
192
        this.fireChanges = true;
193

    
194
    }
195

    
196
    @Deprecated
197
    private void init(Number currentValue, int columns, Comparable minValue, Comparable maxValue, Number step, int decimals) {
198

    
199
        JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
200
        JFormattedTextField textField = editor.getTextField();
201
        NumberFormatter formatter = (NumberFormatter) textField.getFormatter();
202
        DecimalFormat format = editor.getFormat();
203
        SpinnerNumberModel model = getNumberModel();
204

    
205
        if (columns > 0) {
206
            textField.setColumns(columns);
207
        }
208
        model.setValue(currentValue);
209

    
210
        // Las siguientes lineas son un chapuza.
211
        //
212
        // Si meto un Double/double en setMaximun/setMinimun
213
        // No deja cambiar el valor asignado desde el UI.
214
        model.setMaximum(hackValue(maxValue));
215
        model.setMinimum(hackValue(minValue));
216
        // Como meta un double en setStepSize tampoco me deja
217
        // incrementar/decrementar el valor
218
        model.setStepSize((int)(Math.ceil(step.doubleValue())));
219
        //
220
        // Esto es lo que esperaba que deberia ir y no va
221
        // model.setMaximum(maxValue);
222
        // model.setMinimum(minValue);
223
        // model.setStepSize(step);
224
        //
225
        // Fin chapuza
226

    
227
        // dump();
228
        format.setMinimumFractionDigits(decimals);
229
        formatter.setAllowsInvalid(true);
230

    
231
        this.fireChanges = true;
232
    }
233
//
234
//    private void dump() {
235
//        SpinnerNumberModel model = getNumberModel();
236
//        logger.info(
237
//                "Current="+model.getValue()+" ("+model.getValue().getClass().getName()+"), "+
238
//                "maxValue="+model.getMaximum()+" ("+model.getMaximum().getClass().getName()+"), "+
239
//                "minValue="+model.getMinimum()+" ("+model.getMinimum().getClass().getName()+"),"+
240
//                "step="+model.getStepSize()+" ("+model.getStepSize().getClass().getName()+")"
241
//        );
242
//    }
243

    
244
    protected SpinnerNumberModel getNumberModel() {
245
        return (SpinnerNumberModel) this.getModel();
246
    }
247

    
248
    private Comparable hackValue(Comparable value) {
249
        if( !(value instanceof Double) ) {
250
            return value;
251
        }
252
        return ((Number)value).intValue();
253
    }
254

    
255
    public int getInteger() {
256
        return getNumberModel().getNumber().intValue();
257
    }
258

    
259
    public double getDouble() {
260
        return getNumberModel().getNumber().doubleValue();
261
    }
262

    
263
    public void setDouble(double v) {
264
        if (this.fireChanges) {
265
            this.fireChanges = false;
266
            try {
267
                setDouble(v);
268
            } finally {
269
                this.fireChanges = true;
270
            }
271
            return;
272
        }
273
        SpinnerNumberModel model = getNumberModel();
274
        model.setValue(v);
275
        //dump();
276
    }
277

    
278
    public void setInteger(int v) {
279
        if (this.fireChanges) {
280
            this.fireChanges = false;
281
            try {
282
                setInteger(v);
283
            } finally {
284
                this.fireChanges = true;
285
            }
286
            return;
287
        }
288
        SpinnerNumberModel model = getNumberModel();
289
        model.setValue(v);
290
        // dump();
291
    }
292

    
293
    public double getMaxValue() {
294
        Number n = (Number) getNumberModel().getMaximum();
295
        return n.doubleValue();
296
    }
297

    
298
    public void setMaxValue(double maxValue) {
299
        if (this.fireChanges) {
300
            this.fireChanges = false;
301
            try {
302
                setMaxValue(maxValue);
303
            } finally {
304
                this.fireChanges = true;
305
            }
306
            return;
307
        }
308
        SpinnerNumberModel model = getNumberModel();
309

    
310
        if (model.getValue() instanceof Double) {
311
            model.setMaximum(new Double(maxValue));
312
        } else {
313
            model.setMaximum(new Integer((int) maxValue));
314
        }
315
        // dump();
316
    }
317

    
318
    public double getMinValue() {
319
        Number n = (Number) getNumberModel().getMinimum();
320
        return n.doubleValue();
321
    }
322

    
323
    public void setMinValue(double minValue) {
324
        if (this.fireChanges) {
325
            this.fireChanges = false;
326
            try {
327
                setMinValue(minValue);
328
            } finally {
329
                this.fireChanges = true;
330
            }
331
            return;
332
        }
333
        SpinnerNumberModel model = getNumberModel();
334

    
335
        if (model.getValue() instanceof Double) {
336
            model.setMinimum(new Double(minValue));
337
        } else {
338
            model.setMinimum(new Integer((int) minValue));
339
        }
340
        // dump();
341
    }
342

    
343
    public double getStep() {
344
        Number n = (Number) getNumberModel().getStepSize();
345
        return n.doubleValue();
346
    }
347

    
348
    public void setStep(double step) {
349
        if (this.fireChanges) {
350
            this.fireChanges = false;
351
            try {
352
                setStep(step);
353
            } finally {
354
                this.fireChanges = true;
355
            }
356
            return;
357
        }
358

    
359
        SpinnerNumberModel model = getNumberModel();
360

    
361
        if (model.getValue() instanceof Double) {
362
            model.setStepSize(new Double(step));
363
        } else {
364
            model.setStepSize(new Integer((int) step));
365
        }
366
        // dump();
367
    }
368

    
369
    public void addActionListener(final ActionListener listener) {
370
        // Me guardo los ActionListeners a parte y no los registro
371
        // directamente en el spinner ya que el cliente de JnumberSpiner
372
        // espera que solo se invoque a estos listeners por eventos
373
        // provocados desde el GUI y no por asignar valores a las
374
        // propiedades del JNumberSpinner
375
        this.actionListeners.add(listener);
376
    }
377

    
378
    @Override
379
    protected void fireStateChanged() {
380
        // Disparo los evento normales
381
        super.fireStateChanged();
382
        if( this.fireChanges ) {
383
            // Si los cambios no son producidos por asignacion a las propiedades
384
            // del JNumberSpinner disparo los actionlistener que haya registrados.
385
            for( int i=0; i<this.actionListeners.size(); i ++ ) {
386
                ActionListener listener = (ActionListener) this.actionListeners.get(i);
387
                listener.actionPerformed(new ActionEvent(this, -1, null));
388
            }
389
        }
390
    }
391

    
392

    
393
}