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

History | View | Annotate | Download (12.2 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
        // Esto es lo que esperaba que deberia ir y no va
235
        // model.setMaximum(maxValue);
236
        // model.setMinimum(minValue);
237
        // model.setStepSize(step);
238
        //
239
        // Fin chapuza
240
  
241
        // dump();
242
        format.setMinimumFractionDigits(decimals);
243
        formatter.setAllowsInvalid(true);
244
        
245
        this.fireChanges = true;
246
    }
247
//
248
//    private void dump() {
249
//        SpinnerNumberModel model = getNumberModel();
250
//        logger.info(
251
//                "Current="+model.getValue()+" ("+model.getValue().getClass().getName()+"), "+
252
//                "maxValue="+model.getMaximum()+" ("+model.getMaximum().getClass().getName()+"), "+
253
//                "minValue="+model.getMinimum()+" ("+model.getMinimum().getClass().getName()+"),"+
254
//                "step="+model.getStepSize()+" ("+model.getStepSize().getClass().getName()+")"
255
//        );        
256
//    }
257

    
258
    protected SpinnerNumberModel getNumberModel() {
259
        return (SpinnerNumberModel) this.getModel();
260
    }
261

    
262
    private Comparable hackValue(Comparable value) {
263
        if( !(value instanceof Double) ) {
264
            return value;
265
        }
266
        return ((Number)value).intValue();
267
    }
268
    
269
    public int getInteger() {
270
        return getNumberModel().getNumber().intValue();
271
    }
272

    
273
    public double getDouble() {
274
        return getNumberModel().getNumber().doubleValue();
275
    }
276

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

    
307
    public double getMaxValue() {
308
        Number n = (Number) getNumberModel().getMaximum();
309
        return n.doubleValue();
310
    }
311

    
312
    public void setMaxValue(double maxValue) {
313
        if (this.fireChanges) {
314
            this.fireChanges = false;
315
            try {
316
                setMaxValue(maxValue);
317
            } finally {
318
                this.fireChanges = true;
319
            }
320
            return;
321
        }
322
        SpinnerNumberModel model = getNumberModel();
323

    
324
        if (model.getValue() instanceof Double) {
325
            model.setMaximum(new Double(maxValue));
326
        } else {
327
            model.setMaximum(new Integer((int) maxValue));
328
        }
329
        // dump();
330
    }
331

    
332
    public double getMinValue() {
333
        Number n = (Number) getNumberModel().getMinimum();
334
        return n.doubleValue();
335
    }
336

    
337
    public void setMinValue(double minValue) {
338
        if (this.fireChanges) {
339
            this.fireChanges = false;
340
            try {
341
                setMinValue(minValue);
342
            } finally {
343
                this.fireChanges = true;
344
            }
345
            return;
346
        }
347
        SpinnerNumberModel model = getNumberModel();
348

    
349
        if (model.getValue() instanceof Double) {
350
            model.setMinimum(new Double(minValue));
351
        } else {
352
            model.setMinimum(new Integer((int) minValue));
353
        }
354
        // dump();
355
    }
356

    
357
    public double getStep() {
358
        Number n = (Number) getNumberModel().getStepSize();
359
        return n.doubleValue();
360
    }
361

    
362
    public void setStep(double step) {
363
        if (this.fireChanges) {
364
            this.fireChanges = false;
365
            try {
366
                setStep(step);
367
            } finally {
368
                this.fireChanges = true;
369
            }
370
            return;
371
        }
372
        
373
        SpinnerNumberModel model = getNumberModel();
374

    
375
        if (model.getValue() instanceof Double) {
376
            model.setStepSize(new Double(step));
377
        } else {
378
            model.setStepSize(new Integer((int) step));
379
        }
380
        // dump();
381
    }
382

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

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

    
406

    
407
}