1 7 package javax.swing.text; 8 9 import java.lang.reflect.*; 10 import java.text.*; 11 import java.util.*; 12 import javax.swing.text.*; 13 14 76 public class NumberFormatter extends InternationalFormatter { 77 78 private String specialChars; 79 80 85 public NumberFormatter() { 86 this(NumberFormat.getNumberInstance()); 87 } 88 89 94 public NumberFormatter(NumberFormat format) { 95 super(format); 96 setFormat(format); 97 setAllowsInvalid(true); 98 setCommitsOnValidEdit(false); 99 setOverwriteMode(false); 100 } 101 102 112 public void setFormat(Format format) { 113 super.setFormat(format); 114 115 DecimalFormatSymbols dfs = getDecimalFormatSymbols(); 116 117 if (dfs != null) { 118 StringBuffer sb = new StringBuffer (); 119 120 sb.append(dfs.getCurrencySymbol()); 121 sb.append(dfs.getDecimalSeparator()); 122 sb.append(dfs.getGroupingSeparator()); 123 sb.append(dfs.getInfinity()); 124 sb.append(dfs.getInternationalCurrencySymbol()); 125 sb.append(dfs.getMinusSign()); 126 sb.append(dfs.getMonetaryDecimalSeparator()); 127 sb.append(dfs.getNaN()); 128 sb.append(dfs.getPercent()); 129 sb.append('+'); 130 specialChars = sb.toString(); 131 } 132 else { 133 specialChars = ""; 134 } 135 } 136 137 141 Object stringToValue(String text, Format f) throws ParseException { 142 if (f == null) { 143 return text; 144 } 145 Object value = f.parseObject(text); 146 147 return convertValueToValueClass(value, getValueClass()); 148 } 149 150 157 private Object convertValueToValueClass(Object value, Class valueClass) { 158 if (valueClass != null && (value instanceof Number )) { 159 if (valueClass == Integer .class) { 160 return new Integer (((Number )value).intValue()); 161 } 162 else if (valueClass == Long .class) { 163 return new Long (((Number )value).longValue()); 164 } 165 else if (valueClass == Float .class) { 166 return new Float (((Number )value).floatValue()); 167 } 168 else if (valueClass == Double .class) { 169 return new Double (((Number )value).doubleValue()); 170 } 171 else if (valueClass == Byte .class) { 172 return new Byte (((Number )value).byteValue()); 173 } 174 else if (valueClass == Short .class) { 175 return new Short (((Number )value).shortValue()); 176 } 177 } 178 return value; 179 } 180 181 184 private char getPositiveSign() { 185 return '+'; 186 } 187 188 191 private char getMinusSign() { 192 DecimalFormatSymbols dfs = getDecimalFormatSymbols(); 193 194 if (dfs != null) { 195 return dfs.getMinusSign(); 196 } 197 return '-'; 198 } 199 200 203 private char getDecimalSeparator() { 204 DecimalFormatSymbols dfs = getDecimalFormatSymbols(); 205 206 if (dfs != null) { 207 return dfs.getDecimalSeparator(); 208 } 209 return '.'; 210 } 211 212 215 private DecimalFormatSymbols getDecimalFormatSymbols() { 216 Format f = getFormat(); 217 218 if (f instanceof DecimalFormat) { 219 return ((DecimalFormat)f).getDecimalFormatSymbols(); 220 } 221 return null; 222 } 223 224 226 private boolean isValidInsertionCharacter(char aChar) { 227 return (Character.isDigit(aChar) || specialChars.indexOf(aChar) != -1); 228 } 229 230 231 237 boolean isLegalInsertText(String text) { 238 if (getAllowsInvalid()) { 239 return true; 240 } 241 for (int counter = text.length() - 1; counter >= 0; counter--) { 242 char aChar = text.charAt(counter); 243 244 if (!Character.isDigit(aChar) && 245 specialChars.indexOf(aChar) == -1){ 246 return false; 247 } 248 } 249 return true; 250 } 251 252 256 boolean isLiteral(Map attrs) { 257 if (!super.isLiteral(attrs)) { 258 if (attrs == null) { 259 return false; 260 } 261 int size = attrs.size(); 262 263 if (attrs.get(NumberFormat.Field.GROUPING_SEPARATOR) != null) { 264 size--; 265 if (attrs.get(NumberFormat.Field.INTEGER) != null) { 266 size--; 267 } 268 } 269 if (attrs.get(NumberFormat.Field.EXPONENT_SYMBOL) != null) { 270 size--; 271 } 272 if (attrs.get(NumberFormat.Field.PERCENT) != null) { 273 size--; 274 } 275 if (attrs.get(NumberFormat.Field.PERMILLE) != null) { 276 size--; 277 } 278 if (attrs.get(NumberFormat.Field.CURRENCY) != null) { 279 size--; 280 } 281 if (attrs.get(NumberFormat.Field.SIGN) != null) { 282 size--; 283 } 284 if (size == 0) { 285 return true; 286 } 287 return false; 288 } 289 return true; 290 } 291 292 297 boolean isNavigatable(int index) { 298 if (!super.isNavigatable(index)) { 299 if (getBufferedChar(index) == getDecimalSeparator()) { 301 return true; 302 } 303 return false; 304 } 305 return true; 306 } 307 308 312 private NumberFormat.Field getFieldFrom(int index, int direction) { 313 if (isValidMask()) { 314 int max = getFormattedTextField().getDocument().getLength(); 315 AttributedCharacterIterator iterator = getIterator(); 316 317 if (index >= max) { 318 index += direction; 319 } 320 while (index >= 0 && index < max) { 321 iterator.setIndex(index); 322 323 Map attrs = iterator.getAttributes(); 324 325 if (attrs != null && attrs.size() > 0) { 326 Iterator keys = attrs.keySet().iterator(); 327 328 while (keys.hasNext()) { 329 Object key = keys.next(); 330 331 if (key instanceof NumberFormat.Field) { 332 return (NumberFormat.Field)key; 333 } 334 } 335 } 336 index += direction; 337 } 338 } 339 return null; 340 } 341 342 346 void replace(DocumentFilter.FilterBypass fb, int offset, int length, 347 String string, AttributeSet attr) throws BadLocationException { 348 if (!getAllowsInvalid() && length == 0 && string != null && 349 string.length() == 1 && 350 toggleSignIfNecessary(fb, offset, string.charAt(0))) { 351 return; 352 } 353 super.replace(fb, offset, length, string, attr); 354 } 355 356 361 private boolean toggleSignIfNecessary(DocumentFilter.FilterBypass fb, 362 int offset, char aChar) throws 363 BadLocationException { 364 if (aChar == getMinusSign() || aChar == getPositiveSign()) { 365 NumberFormat.Field field = getFieldFrom(offset, -1); 366 Object newValue; 367 368 try { 369 if (field == null || 370 (field != NumberFormat.Field.EXPONENT && 371 field != NumberFormat.Field.EXPONENT_SYMBOL && 372 field != NumberFormat.Field.EXPONENT_SIGN)) { 373 newValue = toggleSign((aChar == getPositiveSign())); 374 } 375 else { 376 newValue = toggleExponentSign(offset, aChar); 378 } 379 if (newValue != null && isValidValue(newValue, false)) { 380 int lc = getLiteralCountTo(offset); 381 String string = valueToString(newValue); 382 383 fb.remove(0, fb.getDocument().getLength()); 384 fb.insertString(0, string, null); 385 updateValue(newValue); 386 repositionCursor(getLiteralCountTo(offset) - 387 lc + offset, 1); 388 return true; 389 } 390 } catch (ParseException pe) { 391 invalidEdit(); 392 } 393 } 394 return false; 395 } 396 397 401 private boolean isOnlyIntegerField(int offset, int length) { 402 if (isValidMask()) { 403 int start = getAttributeStart(NumberFormat.Field.INTEGER); 404 405 if (start != -1) { 406 AttributedCharacterIterator iterator = getIterator(); 407 408 iterator.setIndex(start); 409 if (offset > start || iterator.getRunLimit( 410 NumberFormat.Field.INTEGER) > (offset + length)) { 411 return false; 412 } 413 return true; 414 } 415 } 416 return false; 417 } 418 419 423 private Object toggleSign(boolean positive) throws ParseException { 424 Object value = stringToValue(getFormattedTextField().getText()); 425 426 if (value != null) { 427 String string = value.toString(); 430 431 if (string != null && string.length() > 0) { 432 if (positive) { 433 if (string.charAt(0) == '-') { 434 string = string.substring(1); 435 } 436 } 437 else { 438 if (string.charAt(0) == '+') { 439 string = string.substring(1); 440 } 441 if (string.length() > 0 && string.charAt(0) != '-') { 442 string = "-" + string; 443 } 444 } 445 if (string != null) { 446 Class valueClass = getValueClass(); 447 448 if (valueClass == null) { 449 valueClass = value.getClass(); 450 } 451 try { 452 Constructor cons = valueClass.getConstructor( 453 new Class [] { String .class }); 454 455 if (cons != null) { 456 return cons.newInstance(new Object []{string}); 457 } 458 } catch (Throwable ex) { } 459 } 460 } 461 } 462 return null; 463 } 464 465 469 private Object toggleExponentSign(int offset, char aChar) throws 470 BadLocationException , ParseException { 471 String string = getFormattedTextField().getText(); 472 int replaceLength = 0; 473 int loc = getAttributeStart(NumberFormat.Field.EXPONENT_SIGN); 474 475 if (loc >= 0) { 476 replaceLength = 1; 477 offset = loc; 478 } 479 if (aChar == getPositiveSign()) { 480 string = getReplaceString(offset, replaceLength, null); 481 } 482 else { 483 string = getReplaceString(offset, replaceLength, 484 new String (new char[] { aChar })); 485 } 486 return stringToValue(string); 487 } 488 } 489 | Popular Tags |