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 @ 42065

History | View | Annotate | Download (12 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
import org.apache.commons.lang3.StringUtils;
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

    
39
public class JNumberSpinner extends JSpinner {
40

    
41
    private static final Logger logger = LoggerFactory.getLogger(JNumberSpinner.class);
42
            
43
    private boolean fireChanges;
44
    private List actionListeners = new ArrayList();
45
    
46
    public JNumberSpinner() {
47
        super(new SpinnerNumberModel());
48
        init(
49
                0.0,
50
                -1,
51
                Double.NEGATIVE_INFINITY,
52
                Double.MAX_VALUE,
53
                1.0,
54
                0
55
        );
56
    }
57

    
58
    public JNumberSpinner(int currentValue) {
59
        super(new SpinnerNumberModel());
60
        init(
61
                currentValue,
62
                -1,
63
                Integer.MIN_VALUE,
64
                Integer.MAX_VALUE,
65
                1.0,
66
                0
67
        );
68
    }
69

    
70
    public JNumberSpinner(int currentValue, int columns) {
71
        super(new SpinnerNumberModel());
72
        init(
73
                currentValue,
74
                columns,
75
                Integer.MIN_VALUE,
76
                Integer.MAX_VALUE,
77
                1,
78
                0
79
        );
80
    }
81

    
82
    public JNumberSpinner(int currentValue, int columns, int minValue, int maxValue, int step) {
83
        super(new SpinnerNumberModel());
84
        init(
85
                currentValue,
86
                columns,
87
                minValue,
88
                maxValue,
89
                step,
90
                0
91
        );
92
    }
93

    
94
    public JNumberSpinner(String currentValue, int columns, int minValue, int maxValue, int step) {
95
        super(new SpinnerNumberModel());
96

    
97
        Number value;
98

    
99
        if (StringUtils.isBlank(currentValue)) {
100
            value = null;
101
        } else {
102
            try {
103
                value = new Integer(Integer.parseInt(currentValue));
104
            } catch (Exception ex) {
105
                value = null;
106
            }
107
        }
108
        init(
109
                value == null ? 0 : value,
110
                columns,
111
                new Integer(minValue),
112
                new Integer(maxValue),
113
                new Integer(step),
114
                0
115
        );
116
        if (value == null) {
117
            JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
118
            JFormattedTextField textField = editor.getTextField();
119
            textField.setText("");
120
        }
121
    }
122

    
123
    public JNumberSpinner(int currentValue, int columns, int minValue, int maxValue, int step, int decimals) {
124
        super(new SpinnerNumberModel());
125
        init(
126
                new Integer(currentValue),
127
                columns,
128
                new Integer(minValue),
129
                new Integer(maxValue),
130
                new Integer(step),
131
                decimals
132
        );
133
    }
134

    
135
    public JNumberSpinner(double currentValue) {
136
        super(new SpinnerNumberModel());
137
        init(
138
                currentValue,
139
                -1,
140
                Double.NEGATIVE_INFINITY,
141
                Double.MAX_VALUE,
142
                1.0,
143
                4
144
        );
145
    }
146

    
147
    public JNumberSpinner(String currentValue, int columns, double minValue, double maxValue, double step) {
148
        this(
149
                currentValue,
150
                columns,
151
                minValue,
152
                maxValue,
153
                step,
154
                0
155
        );
156
    }
157

    
158
    public JNumberSpinner(String currentValue, int columns, double minValue, double maxValue, double step, int decimals) {
159
        super(new SpinnerNumberModel());
160

    
161
        Number value;
162

    
163
        if (StringUtils.isBlank(currentValue)) {
164
            value = null;
165
        } else {
166
            try {
167
                value = new Double(Double.parseDouble(currentValue));
168
            } catch (Exception ex) {
169
                value = null;
170
            }
171
        }
172
        init(
173
                value == null ? 0 : value,
174
                columns,
175
                new Double(minValue),
176
                new Double(maxValue),
177
                new Double(step),
178
                decimals
179
        );
180
        if (value == null) {
181
            JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
182
            JFormattedTextField textField = editor.getTextField();
183
            textField.setText("");
184
        }
185
    }
186

    
187
    public JNumberSpinner(double currentValue, int columns, double minValue, double maxValue, double step) {
188
        super(new SpinnerNumberModel());
189
        init(
190
                currentValue,
191
                columns,
192
                minValue,
193
                maxValue,
194
                step,
195
                4
196
        );
197
    }
198

    
199
    public JNumberSpinner(double currentValue, int columns, double minValue, double maxValue, double step, int decimals) {
200
        super(new SpinnerNumberModel());
201
        init(
202
                new Double(currentValue),
203
                columns,
204
                new Double(minValue),
205
                new Double(maxValue),
206
                new Double(step),
207
                decimals
208
        );
209
    }
210

    
211
    private void init(Number currentValue, int columns, Comparable minValue, Comparable maxValue, Number step, int decimals) {
212

    
213
        JSpinner.NumberEditor editor = (JSpinner.NumberEditor) this.getEditor();
214
        JFormattedTextField textField = editor.getTextField();
215
        NumberFormatter formatter = (NumberFormatter) textField.getFormatter();
216
        DecimalFormat format = editor.getFormat();
217
        SpinnerNumberModel model = getNumberModel();
218

    
219
        if (columns > 0) {
220
            textField.setColumns(columns);
221
        }
222
        model.setValue(currentValue);
223

    
224
        // Las siguientes lineas son un chapuza.
225
        //
226
        // Si meto un Double/double en setMaximun/setMinimun
227
        // No deja cambiar el valor asignado desde el UI.
228
        model.setMaximum(hackValue(maxValue));
229
        model.setMinimum(hackValue(minValue));
230
        // Como meta un double en setStepSize tampoco me deja
231
        // incrementar/decrementar el valor
232
        model.setStepSize((int)(Math.ceil(step.doubleValue())));
233
        //
234
        // Fin chapuza
235
  
236
        // dump();
237
        format.setMinimumFractionDigits(decimals);
238
        formatter.setAllowsInvalid(true);
239
        
240
        this.fireChanges = true;
241
    }
242

    
243
    private void dump() {
244
        SpinnerNumberModel model = getNumberModel();
245
        logger.info(
246
                "Current="+model.getValue()+" ("+model.getValue().getClass().getName()+"), "+
247
                "maxValue="+model.getMaximum()+" ("+model.getMaximum().getClass().getName()+"), "+
248
                "minValue="+model.getMinimum()+" ("+model.getMinimum().getClass().getName()+"),"+
249
                "step="+model.getStepSize()+" ("+model.getStepSize().getClass().getName()+")"
250
        );        
251
    }
252

    
253
    protected SpinnerNumberModel getNumberModel() {
254
        return (SpinnerNumberModel) this.getModel();
255
    }
256

    
257
    private Comparable hackValue(Comparable value) {
258
        if( !(value instanceof Double) ) {
259
            return value;
260
        }
261
        return ((Number)value).intValue();
262
    }
263
    
264
    public int getInteger() {
265
        return getNumberModel().getNumber().intValue();
266
    }
267

    
268
    public double getDouble() {
269
        return getNumberModel().getNumber().doubleValue();
270
    }
271

    
272
    public void setDouble(double v) {
273
        if (this.fireChanges) {
274
            this.fireChanges = false;
275
            try {
276
                setDouble(v);
277
            } finally {
278
                this.fireChanges = true;
279
            }
280
            return;
281
        }
282
        SpinnerNumberModel model = getNumberModel();
283
        model.setValue(v);
284
        dump();
285
    }
286
    
287
    public void setInteger(int v) {
288
        if (this.fireChanges) {
289
            this.fireChanges = false;
290
            try {
291
                setInteger(v);
292
            } finally {
293
                this.fireChanges = true;
294
            }
295
            return;
296
        }
297
        SpinnerNumberModel model = getNumberModel();
298
        model.setValue(v);
299
        dump();
300
    }
301

    
302
    public double getMaxValue() {
303
        Number n = (Number) getNumberModel().getMaximum();
304
        return n.doubleValue();
305
    }
306

    
307
    public void setMaxValue(double maxValue) {
308
        if (this.fireChanges) {
309
            this.fireChanges = false;
310
            try {
311
                setMaxValue(maxValue);
312
            } finally {
313
                this.fireChanges = true;
314
            }
315
            return;
316
        }
317
        SpinnerNumberModel model = getNumberModel();
318

    
319
        if (model.getValue() instanceof Double) {
320
            model.setMaximum(new Double(maxValue));
321
        } else {
322
            model.setMaximum(new Integer((int) maxValue));
323
        }
324
        dump();
325
    }
326

    
327
    public double getMinValue() {
328
        Number n = (Number) getNumberModel().getMinimum();
329
        return n.doubleValue();
330
    }
331

    
332
    public void setMinValue(double minValue) {
333
        if (this.fireChanges) {
334
            this.fireChanges = false;
335
            try {
336
                setMinValue(minValue);
337
            } finally {
338
                this.fireChanges = true;
339
            }
340
            return;
341
        }
342
        SpinnerNumberModel model = getNumberModel();
343

    
344
        if (model.getValue() instanceof Double) {
345
            model.setMinimum(new Double(minValue));
346
        } else {
347
            model.setMinimum(new Integer((int) minValue));
348
        }
349
        dump();
350
    }
351

    
352
    public double getStep() {
353
        Number n = (Number) getNumberModel().getStepSize();
354
        return n.doubleValue();
355
    }
356

    
357
    public void setStep(double step) {
358
        if (this.fireChanges) {
359
            this.fireChanges = false;
360
            try {
361
                setStep(step);
362
            } finally {
363
                this.fireChanges = true;
364
            }
365
            return;
366
        }
367
        
368
        SpinnerNumberModel model = getNumberModel();
369

    
370
        if (model.getValue() instanceof Double) {
371
            model.setStepSize(new Double(step));
372
        } else {
373
            model.setStepSize(new Integer((int) step));
374
        }
375
        dump();
376
    }
377

    
378
    public void addActionListener(final ActionListener listener) {
379
        // Me guardo los ActionListeners a parte y no los registro 
380
        // directamente en el spinner ya que el cliente de JnumberSpiner 
381
        // espera que solo se invoque a estos listeners por eventos
382
        // provocados desde el GUI y no por asignar valores a las
383
        // propiedades del JNumberSpinner
384
        this.actionListeners.add(listener);
385
    }
386

    
387
    @Override
388
    protected void fireStateChanged() {
389
        // Disparo los evento normales
390
        super.fireStateChanged();
391
        if( this.fireChanges ) {
392
            // Si los cambios no son producidos por asignacion a las propiedades
393
            // del JNumberSpinner disparo los actionlistener que haya registrados.
394
            for( int i=0; i<this.actionListeners.size(); i ++ ) {
395
                ActionListener listener = (ActionListener) this.actionListeners.get(i);
396
                listener.actionPerformed(new ActionEvent(this, -1, null));
397
            }
398
        }
399
    }
400

    
401

    
402
}