/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package tufts.vue;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
/**
* NumericField
* This class is a subclass of JTextField that supports
* numeric inputs for integers or real decimal numbers.
*
* The input is set on construction to be one of four modes:
* NUMERIC - any decimal number
* POSITIVE_NUMERIC - only positive real numbers
* INTEGER - any integer value
* POSITIVE_INTEGER - only positive integers.
*
* It uses the java Document override to deal with the filtering.
**/
public class NumericField extends JTextField {
//////////////
// Statics
//////////////
/** Mode supports numeric values **/
static public final int NUMERIC = 1;
/** Mode supports integer values **/
static public final int INTEGER = 2;
/** Mode isupports positive numeric values **/
static public final int POSITIVE_NUMERIC = 3;
/** Mode supports positive, integer values (whole numbers) **/
static public final int POSITIVE_INTEGER = 4;
static private final String sValidCharsNumeric = "0123456789-.";
/////////////
// Fields
//////////////
/** the mode for this editor field **/
protected int mMode;
/** the valid chars allowed in the field **/
protected String mValidChars;
///////////////
// Constructors
////////////////
/**
* Create a new NumericField with the specified mode
**/
public NumericField(int pMode) {
super();
setDocument( new NumericDocument(this));
setMode(pMode);
}
/**
* Create a new NumericField with the specified mode and width
**/
public NumericField(int pMode, int pColumns) {
this(pMode);
setColumns( pColumns);
}
////////////////
// Methods
////////////////
/**
* setValue
* Sets the value of this field from an integer.
*
**/
public void setValue(int pValue) {
if( (pValue < 0) && (mMode == POSITIVE_INTEGER || mMode == POSITIVE_NUMERIC)) {
//throw new IllegalArgumentException(pValue + " is < 0, field requires positive value");
throw new IllegalArgumentException( "NumericFieldF - Requires Positive Value" );
}
else {
super.setText(Integer.toString(pValue));
}
}
/**
* setValue
* Set the value of this field from a double.
*
**/
public void setValue(double pValue) {
if (mMode == INTEGER || mMode == POSITIVE_INTEGER) {
throw new IllegalArgumentException( "NumericField - Requires Integer" );
}
else
if (mMode == POSITIVE_NUMERIC) {
throw new IllegalArgumentException( "NumericField - Requires Positive Value" );
}
else {
setText( Double.toString( pValue));
}
}
/**
* getValue
* This gets the value as a double
**/
public double getValue() {
String val = getText();
if (val == null || val.length() == 0) {
return 0.0;
}
return Double.valueOf(val).doubleValue();
}
/**
* setMode
* This sets the mode of this NumericField
* to the type specified. It also sets the
* valid charas that are allowed from the keyboard.
**/
private void setMode(int pMode) {
mMode = pMode;
switch(pMode) {
case NUMERIC:
mValidChars = "0123456789-.";
break;
case INTEGER:
mValidChars = "0123456789-";
break;
case POSITIVE_NUMERIC:
mValidChars = "0123456789-.";
break;
case POSITIVE_INTEGER:
mValidChars = "0123456789";
break;
}
}
/**
* NumericDocument is a document class that accepts only numeric
* input and is sensitive to the mode setting of the NumericField
* that owns the document.
**/
private class NumericDocument extends PlainDocument {
NumericField mDocNumericField = null;
private NumericDocument(NumericField pField) {
mDocNumericField = pField;
}
public void insertString(int offset, String str, AttributeSet a)
throws BadLocationException {
char[] source = str.toCharArray();
String text;
for (int n = 0 ; n < source.length ; n++) {
char c = source[n];
if (mValidChars.indexOf(c) == -1)
return;
if (c == '-' && offset > 0)
return;
if (c == '.' && ((text = mDocNumericField.getText()) != null) && text.indexOf('.') != -1)
return;
}
super.insertString(offset, str, a);
}
}
}