svn-gvsig-desktop / tags / v1_0_2_Build_915 / applications / appgvSIG / src / com / iver / cit / gvsig / gui / ValidatingTextField.java @ 12217
History | View | Annotate | Download (13.9 KB)
1 | 312 | fernando | /*
|
---|---|---|---|
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 | 1103 | fjp | /* 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 | 312 | fernando | package com.iver.cit.gvsig.gui; |
73 | |||
74 | 7053 | caballero | import java.awt.Component; |
75 | 312 | fernando | import java.awt.event.FocusAdapter; |
76 | import java.awt.event.FocusEvent; |
||
77 | |||
78 | 7053 | caballero | import javax.swing.JOptionPane; |
79 | 312 | fernando | import javax.swing.JTextField; |
80 | import javax.swing.text.AttributeSet; |
||
81 | import javax.swing.text.BadLocationException; |
||
82 | import javax.swing.text.PlainDocument; |
||
83 | |||
84 | 7053 | caballero | import com.iver.andami.PluginServices; |
85 | 312 | fernando | 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 | 7053 | caballero | |
316 | 312 | fernando | /**
|
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 | 7053 | caballero | |
333 | 312 | fernando | /**
|
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 | 7053 | caballero | } |
358 | 312 | fernando | |
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 | 7053 | caballero | String s=""; |
368 | s=""+ Math.max(minimum, Integer.parseInt(text)); |
||
369 | return s;
|
||
370 | 312 | fernando | } |
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 | 7053 | caballero | String s=""; |
410 | s=""+ Math.min(maximum, Integer.parseInt(text)); |
||
411 | return s;
|
||
412 | 312 | fernando | } |
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 | 7053 | caballero | 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 | 312 | fernando | |
453 | 7053 | caballero | |
454 | 312 | fernando | return result;
|
455 | } |
||
456 | } |
||
457 | } |