Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_904 / applications / appgvSIG / src / com / iver / cit / gvsig / gui / ValidatingTextField.java @ 10724

History | View | Annotate | Download (13.9 KB)

1
/*
2
 * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
3
 * for visualizing and manipulating spatial features with geometry and attributes.
4
 *
5
 * Copyright (C) 2003 Vivid Solutions
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
 *
21
 * For more information, contact:
22
 *
23
 * Vivid Solutions
24
 * Suite #1A
25
 * 2328 Government Street
26
 * Victoria BC  V8T 5G5
27
 * Canada
28
 *
29
 * (250)385-6040
30
 * www.vividsolutions.com
31
 */
32
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
33
 *
34
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
35
 *
36
 * This program is free software; you can redistribute it and/or
37
 * modify it under the terms of the GNU General Public License
38
 * as published by the Free Software Foundation; either version 2
39
 * of the License, or (at your option) any later version.
40
 *
41
 * This program is distributed in the hope that it will be useful,
42
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44
 * GNU General Public License for more details.
45
 *
46
 * You should have received a copy of the GNU General Public License
47
 * along with this program; if not, write to the Free Software
48
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
49
 *
50
 * For more information, contact:
51
 *
52
 *  Generalitat Valenciana
53
 *   Conselleria d'Infraestructures i Transport
54
 *   Av. Blasco Ib??ez, 50
55
 *   46010 VALENCIA
56
 *   SPAIN
57
 *
58
 *      +34 963862235
59
 *   gvsig@gva.es
60
 *      www.gvsig.gva.es
61
 *
62
 *    or
63
 *
64
 *   IVER T.I. S.A
65
 *   Salamanca 50
66
 *   46005 Valencia
67
 *   Spain
68
 *
69
 *   +34 963163400
70
 *   dac@iver.es
71
 */
72
package com.iver.cit.gvsig.gui;
73

    
74
import java.awt.Component;
75
import java.awt.event.FocusAdapter;
76
import java.awt.event.FocusEvent;
77

    
78
import javax.swing.JOptionPane;
79
import javax.swing.JTextField;
80
import javax.swing.text.AttributeSet;
81
import javax.swing.text.BadLocationException;
82
import javax.swing.text.PlainDocument;
83

    
84
import com.iver.andami.PluginServices;
85
import com.vividsolutions.jts.util.Assert;
86

    
87

    
88
/**
89
 * Prevents the user from entering invalid data.
90
 */
91
public class ValidatingTextField extends JTextField {
92
    public static final Validator LONG_VALIDATOR = new ValidatingTextField.Validator() {
93
            public boolean isValid(String text) {
94
                try {
95
                    Long.parseLong(text.trim());
96

    
97
                    return true;
98
                } catch (NumberFormatException e) {
99
                    return false;
100
                }
101
            }
102
        };
103

    
104
    /**
105
     * Prevents the user from entering invalid integer.
106
     */
107
    public static final Validator INTEGER_VALIDATOR = new ValidatingTextField.Validator() {
108
            public boolean isValid(String text) {
109
                try {
110
                    Integer.parseInt(text.trim());
111

    
112
                    return true;
113
                } catch (NumberFormatException e) {
114
                    return false;
115
                }
116
            }
117
        };
118

    
119
    /**
120
     * Prevents the user from entering invalid double.
121
     */
122
    public static final Validator DOUBLE_VALIDATOR = new ValidatingTextField.Validator() {
123
            public boolean isValid(String text) {
124
                try {
125
                    //Add "0" so user can type "-" [Jon Aquino]
126
                    Double.parseDouble(text.trim() + "0");
127

    
128
                    return true;
129
                } catch (NumberFormatException e) {
130
                    return false;
131
                }
132
            }
133
        };
134

    
135
    /**
136
     * Cleaner that does nothing.
137
     */
138
    public static Cleaner DUMMY_CLEANER = new Cleaner() {
139
            public String clean(String text) {
140
                return text;
141
            }
142
        };
143

    
144
    /**
145
     * The validators allow the user to simply enter "+", "-", or ".". If the user
146
     * doesn't go any farther, this cleaner will set the text to 0, which is reasonable.
147
     */
148
    public static Cleaner NUMBER_CLEANER = new Cleaner() {
149
            public String clean(String text) {
150
                try {
151
                    Double.parseDouble(text.trim());
152

    
153
                    return text;
154
                } catch (NumberFormatException e) {
155
                    return "0";
156
                }
157
            }
158
        };
159

    
160
    /**
161
     * Validator that does nothing.
162
     */
163
    public static Validator DUMMY_VALIDATOR = new Validator() {
164
            public boolean isValid(String text) {
165
                return true;
166
            }
167
        };
168

    
169
    private Cleaner cleaner;
170

    
171
    /**
172
     * Validator that uses dummy cleaner.
173
     */
174
    public ValidatingTextField(String text, int columns,
175
        final Validator validator) {
176
        this(text, columns, LEFT, validator, DUMMY_CLEANER);
177
    }
178

    
179
    /**
180
     * Validator for text fields.
181
     */
182
    public ValidatingTextField(String text, int columns,
183
        int horizontalAlignment, final Validator validator,
184
        final Cleaner cleaner) {
185
        super(text, columns);
186
        this.cleaner = cleaner;
187
        setHorizontalAlignment(horizontalAlignment);
188
        installValidationBehavior(this, validator, cleaner);
189

    
190
        //Clean the text, mainly so that parties wishing to install a BlankCleaner
191
        //need only pass "" for the text. [Jon Aquino]
192
        setText(cleaner.clean(getText()));
193

    
194
        //Bonus: workaround for how GridBagLayout shrinks components to
195
        //minimum sizes if it can't accomodate their preferred sizes. [Jon Aquino]
196
        setMinimumSize(getPreferredSize());
197
    }
198

    
199
    //Hopefully this will let us add validation behaviour to combo boxes. [Jon Aquino]
200
    public static void installValidationBehavior(final JTextField textField,
201
        final Validator validator, final Cleaner cleaner) {
202
        textField.setDocument(new PlainDocument() {
203
                public void insertString(int offs, String str, AttributeSet a)
204
                    throws BadLocationException {
205
                    String currentText = this.getText(0, getLength());
206
                    String beforeOffset = currentText.substring(0, offs);
207
                    String afterOffset = currentText.substring(offs,
208
                            currentText.length());
209
                    String proposedResult = beforeOffset + str + afterOffset;
210
                    if (validator.isValid(cleaner.clean(proposedResult))) {
211
                        super.insertString(offs, str, a);
212
                    }
213
                }
214

    
215
                public void remove(int offs, int len)
216
                    throws BadLocationException {
217
                    String currentText = this.getText(0, getLength());
218
                    String beforeOffset = currentText.substring(0, offs);
219
                    String afterOffset = currentText.substring(len + offs,
220
                            currentText.length());
221
                    String proposedResult = beforeOffset + afterOffset;
222
                    if (validator.isValid(cleaner.clean(proposedResult))) {
223
                        super.remove(offs, len);
224
                    }
225
                }
226
            });
227
        textField.addFocusListener(new FocusAdapter() {
228
                public void focusLost(FocusEvent e) {
229
                    textField.setText(cleaner.clean(textField.getText()));
230
                }
231
            });
232
    }
233

    
234
    public String getText() {
235
        //Focus may not be lost yet (e.g. when syncing with scrollbar) [Jon Aquino]
236
        return cleaner.clean(super.getText());
237
    }
238

    
239
    public double getDouble() {
240
        return Double.parseDouble(getText().trim());
241
    }
242

    
243
    public int getInteger() {
244
        return Integer.parseInt(getText().trim());
245
    }
246

    
247
    public static interface Validator {
248
        public boolean isValid(String text);
249
    }
250

    
251
    public static interface Cleaner {
252
        public String clean(String text);
253
    }
254

    
255
/**
256
 * Implements validator with a greater than threshold.
257
 */
258

    
259
    public static class GreaterThanValidator implements Validator {
260
        private double threshold;
261

    
262
        public GreaterThanValidator(double threshold) {
263
            this.threshold = threshold;
264
        }
265

    
266
        public boolean isValid(String text) {
267
            return Double.parseDouble(text.trim()) > threshold;
268
        }
269
    }
270
/**
271
 * Implements validator with a less than threshold.
272
 */
273

    
274
    public static class LessThanValidator implements Validator {
275
        private double threshold;
276

    
277
        public LessThanValidator(double threshold) {
278
            this.threshold = threshold;
279
        }
280

    
281
        public boolean isValid(String text) {
282
            return Double.parseDouble(text.trim()) < threshold;
283
        }
284
    }
285
/**
286
 * Implements validator with a greater than or equal to threshold.
287
 */
288

    
289
    public static class GreaterThanOrEqualValidator implements Validator {
290
        private double threshold;
291

    
292
        public GreaterThanOrEqualValidator(double threshold) {
293
            this.threshold = threshold;
294
        }
295

    
296
        public boolean isValid(String text) {
297
            return Double.parseDouble(text.trim()) >= threshold;
298
        }
299
    }
300
/**
301
 * Implements validator with a less than or equal to threshold.
302
 */
303

    
304
    public static class LessThanOrEqualValidator implements Validator {
305
        private double threshold;
306

    
307
        public LessThanOrEqualValidator(double threshold) {
308
            this.threshold = threshold;
309
        }
310

    
311
        public boolean isValid(String text) {
312
            return Double.parseDouble(text.trim()) <= threshold;
313
        }
314
    }
315

    
316
    /**
317
 * Implements cleaner which cleans up blank strings.
318
 */
319

    
320

    
321
    public static class BlankCleaner implements Cleaner {
322
        private String replacement;
323

    
324
        public BlankCleaner(String replacement) {
325
            this.replacement = replacement;
326
        }
327

    
328
        public String clean(String text) {
329
            return (text.trim().length() == 0) ? replacement : text;
330
        }
331
    }
332

    
333
    /**
334
     * Allow the user to start typing a number with "-" or "."
335
     * @author jaquino
336
     *
337
     * To change the template for this generated type comment go to
338
     * Window>Preferences>Java>Code Generation>Code and Comments
339
     */
340
    public static class NumberCleaner implements Cleaner {
341
        private String textToAppend;
342

    
343
        public NumberCleaner(String textToAppend) {
344
            this.textToAppend = textToAppend;
345
        }
346

    
347
        public String clean(String text) {
348
            if (text.trim().length() == 0) { return text; }
349
            try {
350
                Double.parseDouble(text);
351
                return text;
352
            }
353
            catch (NumberFormatException e) {
354
                return text + textToAppend;
355
            }
356
        }
357
    }
358

    
359
    public static class MinIntCleaner implements Cleaner {
360
        private int minimum;
361

    
362
        public MinIntCleaner(int minimum) {
363
            this.minimum = minimum;
364
        }
365

    
366
        public String clean(String text) {
367
                String s="";
368
                s=""+ Math.max(minimum, Integer.parseInt(text));
369
                return s;
370
        }
371
    }
372

    
373
/**
374
 * Extends CompositeValidator to validat that integers is within a set of boundary values.
375
 */
376
    public static class BoundedIntValidator extends CompositeValidator {
377
        public BoundedIntValidator(int min, int max) {
378
            super(new Validator[] {
379
                    INTEGER_VALIDATOR, new GreaterThanOrEqualValidator(min),
380
                    new LessThanOrEqualValidator(max)
381
                });
382
            Assert.isTrue(min < max);
383
        }
384
    }
385

    
386
    public static class BoundedDoubleValidator extends CompositeValidator {
387
        public BoundedDoubleValidator(double min, boolean includeMin,
388
            double max, boolean includeMax) {
389
            super(new Validator[] {
390
                    DOUBLE_VALIDATOR,
391
                    includeMin
392
                    ? (Validator) new GreaterThanOrEqualValidator(min)
393
                    : new GreaterThanValidator(min),
394
                    includeMax ? (Validator) new LessThanOrEqualValidator(max)
395
                               : new LessThanValidator(max)
396
                });
397
            Assert.isTrue(min < max);
398
        }
399
    }
400

    
401
    public static class MaxIntCleaner implements Cleaner {
402
        private int maximum;
403

    
404
        public MaxIntCleaner(int maximum) {
405
            this.maximum = maximum;
406
        }
407

    
408
        public String clean(String text) {
409
                String s="";
410
                s=""+ Math.min(maximum, Integer.parseInt(text));
411
                return s;
412
        }
413
    }
414
/**
415
 * Implements validator to check for more than one condition.
416
 */
417

    
418
    public static class CompositeValidator implements Validator {
419
        private Validator[] validators;
420

    
421
        public CompositeValidator(Validator[] validators) {
422
            this.validators = validators;
423
        }
424

    
425
        public boolean isValid(String text) {
426
            for (int i = 0; i < validators.length; i++) {
427
                if (!validators[i].isValid(text)) {
428
                    return false;
429
                }
430
            }
431

    
432
            return true;
433
        }
434
    }
435

    
436
    public static class CompositeCleaner implements Cleaner {
437
        private Cleaner[] cleaners;
438

    
439
        public CompositeCleaner(Cleaner[] cleaners) {
440
            this.cleaners = cleaners;
441
        }
442

    
443
        public String clean(String text) {
444
            String result = text;
445
            try{
446
                    for (int i = 0; i < cleaners.length; i++) {
447
                            result = cleaners[i].clean(result);
448
                    }
449
                }catch (NumberFormatException e) {
450
                                    JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"numero_incorrecto"));
451
                   }
452

    
453

    
454
            return result;
455
        }
456
    }
457
}