KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sshtools > ui > swing > NumericTextField


1 /*
2  * SSHTools - Java SSH2 API
3  *
4  * Copyright (C) 2002 Lee David Painter.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * You may also distribute it and/or modify it under the terms of the
12  * Apache style J2SSH Software License. A copy of which should have
13  * been provided with the distribution.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * License document supplied with your distribution for more details.
19  *
20  */

21
22 package com.sshtools.ui.swing;
23
24 import java.awt.Color JavaDoc;
25 import java.awt.event.FocusEvent JavaDoc;
26 import java.text.DecimalFormat JavaDoc;
27 import java.text.DecimalFormatSymbols JavaDoc;
28 import java.text.NumberFormat JavaDoc;
29 import java.text.ParseException JavaDoc;
30 import javax.swing.JTextField JavaDoc;
31 import javax.swing.text.AttributeSet JavaDoc;
32 import javax.swing.text.BadLocationException JavaDoc;
33 import javax.swing.text.PlainDocument JavaDoc;
34
35 /**
36  *
37  *
38  * @author $author$
39  */

40 public class NumericTextField
41     extends XTextField {
42   private Color JavaDoc positiveBackground;
43   private DecimalFormatSymbols JavaDoc symbols;
44
45   // Private instance variables
46
private NumberFormat JavaDoc numberFormat;
47   private boolean selectAllOnFocusGain;
48   private int wColumnWidth;
49
50   /**
51    * Creates a new NumericTextField object.
52    *
53    * @param min
54    * @param max
55    */

56   public NumericTextField(Number JavaDoc min, Number JavaDoc max) {
57     this(min, max, min);
58   }
59
60   /**
61    * Creates a new NumericTextField object.
62    *
63    * @param min
64    * @param max
65    * @param initial
66    * @param rightJustify
67    */

68   public NumericTextField(Number JavaDoc min, Number JavaDoc max, Number JavaDoc initial,
69                           boolean rightJustify) {
70     this(min, max, initial, rightJustify, null);
71   }
72
73   /**
74    * Creates a new NumericTextField object.
75    *
76    * @param min
77    * @param max
78    * @param initial
79    */

80   public NumericTextField(Number JavaDoc min, Number JavaDoc max, Number JavaDoc initial) {
81     this(min, max, initial, true);
82   }
83
84   /**
85    * Creates a new NumericTextField object.
86    *
87    * @param min
88    * @param max
89    * @param initial
90    * @param rightJustify
91    * @param numberFormat
92    *
93    * @throws IllegalArgumentException
94    */

95   public NumericTextField(Number JavaDoc min, Number JavaDoc max, Number JavaDoc initial,
96                           boolean rightJustify, NumberFormat JavaDoc numberFormat) {
97     super(Math.max(min.toString().length(), max.toString().length()));
98     setNumberFormat(numberFormat);
99
100     if (min.getClass().equals(max.getClass())
101         && max.getClass().equals(initial.getClass())) {
102       setDocument(new ADocument(min, max));
103       setValue(initial);
104     }
105     else {
106       throw new IllegalArgumentException JavaDoc(
107           "All arguments must be of the same class");
108     }
109
110     setRightJustify(rightJustify);
111   }
112
113   /*
114    * Overides <code>JTextFields</codes> calculation of the width of a single
115    * character (M space)
116    *
117    * @return column width based on '9'
118    * public int getColumnWidth() {
119    * if (wColumnWidth==0) {
120    * FontMetrics metrics = getFontMetrics(getFont());
121    * wColumnWidth = metrics.charWidth('W');
122    * }
123    * return wColumnWidth;
124    * }
125    */

126   protected void processFocusEvent(FocusEvent JavaDoc e) {
127     super.processFocusEvent(e);
128
129     if (!e.isTemporary()) {
130       switch (e.getID()) {
131         case FocusEvent.FOCUS_LOST:
132
133           if (getNumberFormat() != null) {
134             String JavaDoc s = getNumberFormat().format(getValue()).toString();
135
136             if (!getText().equals(s)) {
137               setText(s);
138             }
139           }
140
141           break;
142
143         case FocusEvent.FOCUS_GAINED:
144
145           if (isSelectAllOnFocusGain()) {
146             selectAll();
147           }
148
149           break;
150       }
151     }
152   }
153
154   /**
155    *
156    *
157    * @return
158    */

159   public boolean isSelectAllOnFocusGain() {
160     return selectAllOnFocusGain;
161   }
162
163   /**
164    *
165    *
166    * @param selectAllOnFocusGain
167    */

168   public void setSelectAllOnFocusGain(boolean selectAllOnFocusGain) {
169     this.selectAllOnFocusGain = selectAllOnFocusGain;
170   }
171
172   /**
173    *
174    *
175    * @param max
176    */

177   public void setMaximum(Number JavaDoc max) {
178     ( (ADocument) getDocument()).setMaximum(max);
179   }
180
181   /**
182    *
183    *
184    * @return
185    */

186   public Number JavaDoc getMaximum() {
187     return ( (ADocument) getDocument()).max;
188   }
189
190   /**
191    *
192    *
193    * @param min
194    */

195   public void setMinimum(Number JavaDoc min) {
196     ( (ADocument) getDocument()).setMinimum(min);
197   }
198
199   /**
200    *
201    *
202    * @return
203    */

204   public Number JavaDoc getMinimum() {
205     return ( (ADocument) getDocument()).min;
206   }
207
208   /**
209    *
210    *
211    * @param numberFormat
212    */

213   public void setNumberFormat(NumberFormat JavaDoc numberFormat) {
214     this.numberFormat = numberFormat;
215
216     if (numberFormat instanceof DecimalFormat JavaDoc) {
217       symbols = ( (DecimalFormat JavaDoc) numberFormat).getDecimalFormatSymbols();
218     }
219     else {
220       symbols = new DecimalFormatSymbols JavaDoc();
221     }
222   }
223
224   /**
225    *
226    *
227    * @return
228    */

229   public NumberFormat JavaDoc getNumberFormat() {
230     return numberFormat;
231   }
232
233   /**
234    *
235    *
236    * @param rightJustify
237    */

238   public void setRightJustify(boolean rightJustify) {
239     setHorizontalAlignment(rightJustify ? JTextField.RIGHT : JTextField.LEFT);
240   }
241
242   /**
243    *
244    *
245    * @return
246    */

247   public boolean isRightJustify() {
248     return getHorizontalAlignment() == JTextField.RIGHT;
249   }
250
251   /**
252    *
253    *
254    * @param s
255    */

256   public void setText(String JavaDoc s) {
257     ADocument doc = (ADocument) getDocument();
258     Number JavaDoc oldValue = doc.currentVal;
259
260     try {
261       doc.currentVal = doc.parse(s);
262     }
263     catch (Exception JavaDoc e) {
264       e.printStackTrace();
265
266       return;
267     }
268
269     if (oldValue != doc.currentVal) {
270       doc.checkingEnabled = false;
271       super.setText(s);
272       doc.checkingEnabled = true;
273     }
274   }
275
276   /**
277    *
278    *
279    * @param i
280    */

281   public void setValue(Number JavaDoc i) {
282     setText(i.toString());
283   }
284
285   /**
286    *
287    *
288    * @return
289    */

290   public Number JavaDoc getValue() {
291     return ( (ADocument) getDocument()).getValue();
292   }
293
294   // Supporting classes
295
class ADocument
296       extends PlainDocument JavaDoc {
297     Number JavaDoc currentVal;
298     Number JavaDoc max;
299     Number JavaDoc min;
300     boolean checkingEnabled = true;
301     boolean rightJustify = true;
302
303     public ADocument(Number JavaDoc min, Number JavaDoc max) {
304       this.min = min;
305       this.max = max;
306
307       if (min.getClass().equals(Byte JavaDoc.class)) {
308         currentVal = new Byte JavaDoc( (byte) 0);
309       }
310       else {
311         if (min.getClass().equals(Short JavaDoc.class)) {
312           currentVal = new Short JavaDoc( (short) 0);
313         }
314         else {
315           if (min.getClass().equals(Integer JavaDoc.class)) {
316             currentVal = new Integer JavaDoc(0);
317           }
318           else {
319             if (min.getClass().equals(Long JavaDoc.class)) {
320               currentVal = new Long JavaDoc(0L);
321             }
322             else {
323               if (min.getClass().equals(Float JavaDoc.class)) {
324                 currentVal = new Float JavaDoc(0f);
325               }
326               else {
327                 currentVal = new Double JavaDoc(0d);
328               }
329             }
330           }
331         }
332       }
333     }
334
335     public void setMaximum(Number JavaDoc max) {
336       this.max = max;
337     }
338
339     public void setMinimum(Number JavaDoc min) {
340       this.min = min;
341     }
342
343     public void setRightJustify(boolean rightJustify) {
344       this.rightJustify = rightJustify;
345     }
346
347     public boolean isRightJustify() {
348       return rightJustify;
349     }
350
351     public Number JavaDoc getValue() {
352       return currentVal;
353     }
354
355     public void insertString(int offs, String JavaDoc str, AttributeSet JavaDoc a) throws
356         BadLocationException JavaDoc {
357       if (str == null) {
358         return;
359       }
360
361       if (!checkingEnabled) {
362         super.insertString(offs, str, a);
363
364         return;
365       }
366
367       String JavaDoc proposedResult = null;
368
369       if (getLength() == 0) {
370         proposedResult = str;
371       }
372       else {
373         StringBuffer JavaDoc currentBuffer = new StringBuffer JavaDoc(getText(0,
374             getLength()));
375         currentBuffer.insert(offs, str);
376         proposedResult = currentBuffer.toString();
377       }
378
379       try {
380         currentVal = parse(proposedResult);
381         super.insertString(offs, str, a);
382       }
383       catch (Exception JavaDoc e) {
384       }
385     }
386
387     public Number JavaDoc parse(String JavaDoc proposedResult) throws NumberFormatException JavaDoc {
388       Double JavaDoc d = new Double JavaDoc(0d);
389
390       // See if the proposed result matches the number format (if any)
391
if (!proposedResult.equals(String.valueOf(symbols.getMinusSign()))
392           && (proposedResult.length() != 0)) {
393         if (getNumberFormat() != null) {
394           // Strip out everything from the proposed result other than the
395
// numbers and and decimal separators
396
StringBuffer JavaDoc sB = new StringBuffer JavaDoc();
397
398           for (int i = 0; i < proposedResult.length(); i++) {
399             char ch = proposedResult.charAt(i);
400
401             if ( (ch == symbols.getDecimalSeparator())
402                 || ( (ch >= '0') && (ch <= '9'))) {
403               sB.append(ch);
404             }
405           }
406
407           String JavaDoc s = sB.toString();
408
409           // Find out how many digits there are before the decimal place
410
int i = 0;
411
412           for (;
413                (i < s.length())
414                && (s.charAt(i) != symbols.getDecimalSeparator());
415                i++) {
416             ;
417           }
418
419           int before = i;
420           int after = 0;
421
422           if (before < s.length()) {
423             after = s.length() - i - 1;
424           }
425
426           if (before > getNumberFormat().getMaximumIntegerDigits()) {
427             throw new NumberFormatException JavaDoc(
428                 "More digits BEFORE the decimal separator than allowed:"
429                 + proposedResult);
430           }
431
432           if (after > getNumberFormat().getMaximumFractionDigits()) {
433             throw new NumberFormatException JavaDoc(
434                 "More digits AFTER the decimal separator than allowed:"
435                 + proposedResult);
436           }
437
438           // Now try to parse the field against the number format
439
try {
440             d = new Double JavaDoc(getNumberFormat().parse(proposedResult)
441                            .doubleValue());
442           }
443           catch (ParseException JavaDoc pE) {
444             throw new NumberFormatException JavaDoc("Failed to parse. "
445                                             + proposedResult + pE.getMessage());
446           }
447         }
448         // Just use the default parse
449
else {
450           d = new Double JavaDoc(proposedResult);
451         }
452       }
453
454       // Now determine if the number if within range
455
if ( (d.doubleValue() >= min.doubleValue())
456           && (d.doubleValue() <= max.doubleValue())) {
457         // Now create the real type
458
if (min.getClass().equals(Byte JavaDoc.class)) {
459           return new Byte JavaDoc(d.byteValue());
460         }
461         else {
462           if (min.getClass().equals(Short JavaDoc.class)) {
463             return new Short JavaDoc(d.shortValue());
464           }
465           else {
466             if (min.getClass().equals(Integer JavaDoc.class)) {
467               return new Integer JavaDoc(d.intValue());
468             }
469             else {
470               if (min.getClass().equals(Long JavaDoc.class)) {
471                 return new Long JavaDoc(d.longValue());
472               }
473               else {
474                 if (min.getClass().equals(Float JavaDoc.class)) {
475                   return new Float JavaDoc(d.floatValue());
476                 }
477                 else {
478                   return d;
479                 }
480               }
481             }
482           }
483         }
484       }
485       else {
486         throw new NumberFormatException JavaDoc(d
487                                         + " Is out of range. Minimum is " +
488                                         min.doubleValue()
489                                         + ", Maximum is " + max.doubleValue());
490       }
491     }
492
493     public void remove(int offs, int len) throws BadLocationException JavaDoc {
494       if (!checkingEnabled) {
495         super.remove(offs, len);
496
497         return;
498       }
499
500       String JavaDoc currentText = getText(0, getLength());
501       String JavaDoc beforeOffset = currentText.substring(0, offs);
502       String JavaDoc afterOffset = currentText.substring(len + offs,
503                                                  currentText.length());
504       String JavaDoc proposedResult = beforeOffset + afterOffset;
505
506       try {
507         currentVal = parse(proposedResult);
508         super.remove(offs, len);
509       }
510       catch (Exception JavaDoc e) {
511       }
512     }
513   }
514 }
515
Popular Tags