001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: NumericField.java,v $ 023 Revision 1.13 2004/05/12 18:50:22 markl 024 comment block updates 025 026 Revision 1.12 2004/03/16 06:43:39 markl 027 LocaleManager method change 028 029 Revision 1.11 2003/01/19 09:50:53 markl 030 Javadoc & comment header updates. 031 032 Revision 1.10 2001/03/20 00:54:52 markl 033 Fixed deprecated calls. 034 035 Revision 1.9 2001/03/12 09:27:59 markl 036 Source code and Javadoc cleanup. 037 038 Revision 1.8 1999/10/05 02:55:26 markl 039 Added screenshot 040 041 Revision 1.7 1999/07/29 06:45:19 markl 042 Changes to support length constraints. 043 044 Revision 1.6 1999/07/26 08:51:36 markl 045 Added getGrouping() and setGrouping() methods. 046 047 Revision 1.5 1999/07/25 13:40:54 markl 048 Minor enhancements and bug fixes. 049 050 Revision 1.4 1999/07/19 09:46:35 markl 051 More validation fixes. 052 053 Revision 1.3 1999/07/12 08:51:18 markl 054 Broke out common functionality. 055 056 Revision 1.2 1999/07/09 04:37:54 markl 057 Broke up into two classes. 058 059 Revision 1.1 1999/06/28 08:18:47 markl 060 Initial revision 061 ---------------------------------------------------------------------------- 062*/ 063 064package kiwi.ui; 065 066import java.awt.*; 067import java.awt.event.*; 068import java.text.*; 069import javax.swing.*; 070 071import kiwi.text.*; 072import kiwi.util.*; 073 074/** A subclass of <code>DataField</code> for the input and display of 075 * specialized data values, such as currency amounts, percentages, and decimal 076 * values. 077 * 078 * <p><center> 079 * <img src="snapshot/NumericField.gif"><br> 080 * <i>An example NumericField.</i> 081 * </center> 082 * 083 * @author Mark Lindner 084 */ 085 086public class NumericField extends DataField 087 { 088 private static LocaleManager lm = LocaleManager.getDefault(); 089 private int type, decimals = 2; 090 private double value = 0.0, maxValue, minValue; 091 private boolean hasMaxValue = false, hasMinValue = false, grouping = true; 092 093 /** Construct a new <code>NumericField</code> of the specified width and 094 * a default type of <code>DECIMAL_FORMAT</code>. 095 * 096 * @param width The width of the field. 097 */ 098 099 public NumericField(int width) 100 { 101 this(width, DECIMAL_FORMAT); 102 } 103 104 /** Construct a new <code>NumericField</code> of the specified width, for the 105 * specified value type. 106 * 107 * @param width The width of the field. 108 * @param type A validation type; one of the format constants defined in the 109 * <code>FormatConstants</code> class. 110 * @see kiwi.text.FormatConstants 111 * 112 */ 113 114 public NumericField(int width, int type) 115 { 116 super(width); 117 118 setType(type); 119 setHorizontalAlignment(SwingConstants.RIGHT); 120 setFont(KiwiUtils.boldFont); 121 } 122 123 /** Set the numeric value to be displayed by this field. The value is 124 * formatted as a string, according to the rules of the current locale, 125 * and displayed in the field. Invalid input flagging is automatically 126 * turned off. 127 * 128 * @param value The value. 129 */ 130 131 public synchronized void setValue(double value) 132 { 133 this.value = value; 134 String s = "?"; 135 136 switch(type) 137 { 138 case CURRENCY_FORMAT: 139 s = lm.formatCurrency(value, decimals, grouping); 140 break; 141 142 case PERCENTAGE_FORMAT: 143 s = lm.formatPercentage(value, decimals, grouping); 144 break; 145 146 case INTEGER_FORMAT: 147 s = lm.formatInteger((long)value, grouping); 148 break; 149 150 case DECIMAL_FORMAT: 151 default: 152 s = lm.formatDecimal(value, decimals, grouping); 153 break; 154 } 155 156 setText(s); 157 invalid = false; 158 paintInvalid(invalid); 159 } 160 161 /** Set the numeric value to be displayed by this field. 162 * 163 * @param value The value. This value is cast internally to a double. 164 */ 165 166 public void setValue(float value) 167 { 168 setValue((double)value); 169 } 170 171 /** Set the numeric value to be displayed by this field. 172 * 173 * @param value The value. This value is cast internally to a double. 174 */ 175 176 public void setValue(int value) 177 { 178 setValue((double)value); 179 } 180 181 /** Set the numeric value to be displayed by this field. 182 * 183 * @param value The value. This value is cast internally to a double. 184 */ 185 186 public void setValue(long value) 187 { 188 setValue((double)value); 189 } 190 191 /** Set the numeric value to be displayed by this field. 192 * 193 * @param value The value. This value is cast internally to a double. 194 */ 195 196 public void setValue(short value) 197 { 198 setValue((double)value); 199 } 200 201 /** Set the validation type for this field. 202 * 203 * @param type A validation type; one of the format constants defined in the 204 * <code>FormatConstants</code> class. 205 * @see kiwi.text.FormatConstants 206 */ 207 208 public void setType(int type) 209 { 210 this.type = type; 211 212 if(type == INTEGER_FORMAT) 213 setDecimals(0); 214 else 215 setDecimals(2); 216 217 validateInput(); 218 } 219 220 /** Get the validation type for this field. 221 * 222 * @return The validation type. 223 */ 224 225 public int getType() 226 { 227 return(type); 228 } 229 230 /** Get the value from the field. The value returned is the value that 231 * was parsed by the last call to <code>validateInput()</code>. 232 * 233 * @return The parsed value, or 0.0 if the last call to 234 * <code>validateInput()</code> resulted in a parsing error, or if there was 235 * no previous call to <code>validateInput()</code>. 236 * @see #validateInput 237 */ 238 239 public synchronized double getValue() 240 { 241 String text = getText().trim(); 242 243 try 244 { 245 switch(type) 246 { 247 case CURRENCY_FORMAT: 248 value = lm.parseCurrency(text); 249 break; 250 251 case PERCENTAGE_FORMAT: 252 value = lm.parsePercentage(text); 253 break; 254 255 case INTEGER_FORMAT: 256 value = (double)lm.parseInteger(text); 257 break; 258 259 case DECIMAL_FORMAT: 260 default: 261 value = lm.parseDecimal(text); 262 break; 263 } 264 265 if(hasMinValue && (value < minValue)) 266 invalid = true; 267 268 if(hasMaxValue && (value > maxValue)) 269 invalid = true; 270 } 271 catch(ParseException ex) 272 { 273 invalid = true; 274 } 275 276 return(value); 277 } 278 279 /** Validate the input in this field. 280 * 281 * @return <code>true</code> if the field contains valid input, and 282 * <code>false</code> otherwise. 283 */ 284 285 protected boolean checkInput() 286 { 287 invalid = false; 288 289 double v = getValue(); 290 291 if(!invalid) 292 setValue(v); 293 294 paintInvalid(invalid); 295 296 return(!invalid); 297 } 298 299 /** Set the number of decimals to display to the right of the radix. The 300 * default is 2. 301 * 302 * @param decimals The new decimal count. 303 */ 304 305 public void setDecimals(int decimals) 306 { 307 if(decimals < 0) 308 decimals = 0; 309 310 this.decimals = decimals; 311 } 312 313 /** Get the number of decimals being displayed to the right of the radix. 314 * 315 * @return The decimal count. 316 */ 317 318 public int getDecimals() 319 { 320 return(decimals); 321 } 322 323 /** Set a maximum value constraint. If a value is entered that is greater 324 * than the maximum value, the input will not validate. 325 * 326 * @param value The new maximum value. 327 */ 328 329 public void setMaxValue(double value) 330 { 331 maxValue = value; 332 hasMaxValue = true; 333 } 334 335 /** Set a maximum value constraint. If a value is entered that is greater 336 * than the maximum value, the input will not validate. 337 * 338 * @since Kiwi 1.3 339 * 340 * @param value The new maximum value. 341 */ 342 343 public void setMaxValue(int value) 344 { 345 setMaxValue((double)value); 346 } 347 348 /** Clear the maximum value constraint. 349 */ 350 351 public void clearMaxValue() 352 { 353 hasMaxValue = false; 354 } 355 356 /** Set a minimum value constraint. If a value is entered that is less than 357 * the minimum value, the input will not validate. 358 * 359 * @param value The new minimum value. 360 */ 361 362 public void setMinValue(double value) 363 { 364 minValue = value; 365 hasMinValue = true; 366 } 367 368 /** Set a minimum value constraint. If a value is entered that is less than 369 * the minimum value, the input will not validate. 370 * 371 * @since Kiwi 1.3 372 * 373 * @param value The new minimum value. 374 */ 375 376 public void setMinValue(int value) 377 { 378 setMinValue((double)value); 379 } 380 381 /** Clear the minimum value constraint. 382 */ 383 384 public void clearMinValue() 385 { 386 hasMinValue = false; 387 } 388 389 /** Set the grouping mode for this numeric field. If grouping is turned 390 * off, values will be formatted without grouping characters separating the 391 * thousands. The default mode is on. 392 * 393 * @param grouping A flag specifying whether grouping should be on 394 * (<code>true</code>) or off (<code>false</code>). 395 */ 396 397 public void setGrouping(boolean grouping) 398 { 399 this.grouping = grouping; 400 } 401 402 /** Get the grouping mode for this numeric field. 403 * 404 * @return The current grouping mode. 405 */ 406 407 public boolean getGrouping() 408 { 409 return(grouping); 410 } 411 412 } 413 414/* end of source file */