1 21 22 package com.sshtools.ui.swing; 23 24 import java.awt.Color ; 25 import java.awt.event.FocusEvent ; 26 import java.text.DecimalFormat ; 27 import java.text.DecimalFormatSymbols ; 28 import java.text.NumberFormat ; 29 import java.text.ParseException ; 30 import javax.swing.JTextField ; 31 import javax.swing.text.AttributeSet ; 32 import javax.swing.text.BadLocationException ; 33 import javax.swing.text.PlainDocument ; 34 35 40 public class NumericTextField 41 extends XTextField { 42 private Color positiveBackground; 43 private DecimalFormatSymbols symbols; 44 45 private NumberFormat numberFormat; 47 private boolean selectAllOnFocusGain; 48 private int wColumnWidth; 49 50 56 public NumericTextField(Number min, Number max) { 57 this(min, max, min); 58 } 59 60 68 public NumericTextField(Number min, Number max, Number initial, 69 boolean rightJustify) { 70 this(min, max, initial, rightJustify, null); 71 } 72 73 80 public NumericTextField(Number min, Number max, Number initial) { 81 this(min, max, initial, true); 82 } 83 84 95 public NumericTextField(Number min, Number max, Number initial, 96 boolean rightJustify, NumberFormat 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 ( 107 "All arguments must be of the same class"); 108 } 109 110 setRightJustify(rightJustify); 111 } 112 113 126 protected void processFocusEvent(FocusEvent 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 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 159 public boolean isSelectAllOnFocusGain() { 160 return selectAllOnFocusGain; 161 } 162 163 168 public void setSelectAllOnFocusGain(boolean selectAllOnFocusGain) { 169 this.selectAllOnFocusGain = selectAllOnFocusGain; 170 } 171 172 177 public void setMaximum(Number max) { 178 ( (ADocument) getDocument()).setMaximum(max); 179 } 180 181 186 public Number getMaximum() { 187 return ( (ADocument) getDocument()).max; 188 } 189 190 195 public void setMinimum(Number min) { 196 ( (ADocument) getDocument()).setMinimum(min); 197 } 198 199 204 public Number getMinimum() { 205 return ( (ADocument) getDocument()).min; 206 } 207 208 213 public void setNumberFormat(NumberFormat numberFormat) { 214 this.numberFormat = numberFormat; 215 216 if (numberFormat instanceof DecimalFormat ) { 217 symbols = ( (DecimalFormat ) numberFormat).getDecimalFormatSymbols(); 218 } 219 else { 220 symbols = new DecimalFormatSymbols (); 221 } 222 } 223 224 229 public NumberFormat getNumberFormat() { 230 return numberFormat; 231 } 232 233 238 public void setRightJustify(boolean rightJustify) { 239 setHorizontalAlignment(rightJustify ? JTextField.RIGHT : JTextField.LEFT); 240 } 241 242 247 public boolean isRightJustify() { 248 return getHorizontalAlignment() == JTextField.RIGHT; 249 } 250 251 256 public void setText(String s) { 257 ADocument doc = (ADocument) getDocument(); 258 Number oldValue = doc.currentVal; 259 260 try { 261 doc.currentVal = doc.parse(s); 262 } 263 catch (Exception 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 281 public void setValue(Number i) { 282 setText(i.toString()); 283 } 284 285 290 public Number getValue() { 291 return ( (ADocument) getDocument()).getValue(); 292 } 293 294 class ADocument 296 extends PlainDocument { 297 Number currentVal; 298 Number max; 299 Number min; 300 boolean checkingEnabled = true; 301 boolean rightJustify = true; 302 303 public ADocument(Number min, Number max) { 304 this.min = min; 305 this.max = max; 306 307 if (min.getClass().equals(Byte .class)) { 308 currentVal = new Byte ( (byte) 0); 309 } 310 else { 311 if (min.getClass().equals(Short .class)) { 312 currentVal = new Short ( (short) 0); 313 } 314 else { 315 if (min.getClass().equals(Integer .class)) { 316 currentVal = new Integer (0); 317 } 318 else { 319 if (min.getClass().equals(Long .class)) { 320 currentVal = new Long (0L); 321 } 322 else { 323 if (min.getClass().equals(Float .class)) { 324 currentVal = new Float (0f); 325 } 326 else { 327 currentVal = new Double (0d); 328 } 329 } 330 } 331 } 332 } 333 } 334 335 public void setMaximum(Number max) { 336 this.max = max; 337 } 338 339 public void setMinimum(Number 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 getValue() { 352 return currentVal; 353 } 354 355 public void insertString(int offs, String str, AttributeSet a) throws 356 BadLocationException { 357 if (str == null) { 358 return; 359 } 360 361 if (!checkingEnabled) { 362 super.insertString(offs, str, a); 363 364 return; 365 } 366 367 String proposedResult = null; 368 369 if (getLength() == 0) { 370 proposedResult = str; 371 } 372 else { 373 StringBuffer currentBuffer = new StringBuffer (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 e) { 384 } 385 } 386 387 public Number parse(String proposedResult) throws NumberFormatException { 388 Double d = new Double (0d); 389 390 if (!proposedResult.equals(String.valueOf(symbols.getMinusSign())) 392 && (proposedResult.length() != 0)) { 393 if (getNumberFormat() != null) { 394 StringBuffer sB = new StringBuffer (); 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 s = sB.toString(); 408 409 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 ( 428 "More digits BEFORE the decimal separator than allowed:" 429 + proposedResult); 430 } 431 432 if (after > getNumberFormat().getMaximumFractionDigits()) { 433 throw new NumberFormatException ( 434 "More digits AFTER the decimal separator than allowed:" 435 + proposedResult); 436 } 437 438 try { 440 d = new Double (getNumberFormat().parse(proposedResult) 441 .doubleValue()); 442 } 443 catch (ParseException pE) { 444 throw new NumberFormatException ("Failed to parse. " 445 + proposedResult + pE.getMessage()); 446 } 447 } 448 else { 450 d = new Double (proposedResult); 451 } 452 } 453 454 if ( (d.doubleValue() >= min.doubleValue()) 456 && (d.doubleValue() <= max.doubleValue())) { 457 if (min.getClass().equals(Byte .class)) { 459 return new Byte (d.byteValue()); 460 } 461 else { 462 if (min.getClass().equals(Short .class)) { 463 return new Short (d.shortValue()); 464 } 465 else { 466 if (min.getClass().equals(Integer .class)) { 467 return new Integer (d.intValue()); 468 } 469 else { 470 if (min.getClass().equals(Long .class)) { 471 return new Long (d.longValue()); 472 } 473 else { 474 if (min.getClass().equals(Float .class)) { 475 return new Float (d.floatValue()); 476 } 477 else { 478 return d; 479 } 480 } 481 } 482 } 483 } 484 } 485 else { 486 throw new NumberFormatException (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 { 494 if (!checkingEnabled) { 495 super.remove(offs, len); 496 497 return; 498 } 499 500 String currentText = getText(0, getLength()); 501 String beforeOffset = currentText.substring(0, offs); 502 String afterOffset = currentText.substring(len + offs, 503 currentText.length()); 504 String proposedResult = beforeOffset + afterOffset; 505 506 try { 507 currentVal = parse(proposedResult); 508 super.remove(offs, len); 509 } 510 catch (Exception e) { 511 } 512 } 513 } 514 } 515 | Popular Tags |