acm.gui.IntField Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javakarel Show documentation
Show all versions of javakarel Show documentation
This the original Stanford Karel for Java, packaged for Maven. ACM Library is included. See also https://cs.stanford.edu/people/eroberts/karel-the-robot-learns-java.pdf
The newest version!
/*
* @(#)IntField.java 1.99.1 08/12/08
*/
// ************************************************************************
// * Copyright (c) 2008 by the Association for Computing Machinery *
// * *
// * The Java Task Force seeks to impose few restrictions on the use of *
// * these packages so that users have as much freedom as possible to *
// * use this software in constructive ways and can make the benefits of *
// * that work available to others. In view of the legal complexities *
// * of software development, however, it is essential for the ACM to *
// * maintain its copyright to guard against attempts by others to *
// * claim ownership rights. The full text of the JTF Software License *
// * is available at the following URL: *
// * *
// * http://www.acm.org/jtf/jtf-software-license.pdf *
// * *
// ************************************************************************
// REVISION HISTORY
//
// -- V2.0 --
// Bug fix 2-Mar-07 (ESR, JTFBug 2007-004)
// 1. Fixed bug in the formatting code that allowed the display to
// extend beyond the boundaries of the component.
//
// Bug fix 6-May-07 (ESR, JTFBug 2007-006)
// 1. Fixed various bugs in the localization of numbers.
//
// Feature enhancement 26-May-08 (ESR)
// 1. Added support for serialization.
package acm.gui;
import acm.io.*;
import acm.util.*;
import java.awt.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
/* Class: IntField */
/**
* This class implements a simple interactor that accepts an integer value.
*/
public class IntField extends JTextField {
/* Constructor: IntField() */
/**
* Creates a new field object for entering a int
value.
* The contents of the field are initially blank.
*
* Example: IntField field = new IntField();
*/
public IntField() {
this("", Integer.MIN_VALUE, Integer.MAX_VALUE);
}
/* Constructor: IntField(value) */
/**
* Creates a new field object for entering a int
value.
* The contents of the field initially contain the specified value.
*
* Example: IntField field = new IntField(value);
* @param value The value to store in the field
*/
public IntField(int value) {
this("" + value, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
/* Constructor: IntField(low, high) */
/**
* Creates a new field object for entering a int
value,
* which is constrained to be within the specified range. The contents
* of the field are initially blank.
*
* Example: IntField field = new IntField(low, high);
* @param low The lowest value in the permitted range
* @param high The highest value in the permitted range
*/
public IntField(int low, int high) {
this("", low, high);
}
/* Constructor: IntField(value, low, high) */
/**
* Creates a new field object for entering a int
value,
* which is constrained to be within the specified range. The contents
* of the field initially contain the specified value.
*
* Example: IntField field = new IntField(value, low, high);
* @param value The value to store in the field
* @param low The lowest value in the permitted range
* @param high The highest value in the permitted range
*/
public IntField(int value, int low, int high) {
this("" + value, low, high);
}
/* Private constructor: IntField(str, low, high) */
/**
* Creates a new field object for entering a int
value,
* which is constrained to be within the specified range. The contents
* of the field initially contain the specified string.
*/
private IntField(String str, int low, int high) {
parser = NumberFormat.getNumberInstance(Locale.US);
setBackground(Color.WHITE);
setHorizontalAlignment(RIGHT);
minValue = low;
maxValue = high;
setText(str);
exceptionOnError = false;
}
/* Method: getValue() */
/**
* Returns the value of this field as a int
. If this value is either
* not a legal numeric value or is outside the specified range, this method will
* either pop up a dialog allowing the user to reenter the value or throw an
* ErrorException
depending on the state of the exceptionOnError
* flag.
*
* Example: int n = field.getValue();
* @return The value stored in the field as a int
*/
public int getValue() {
String text = getText().trim();
if (text.length() == 0) {
if (minValue <= 0 && maxValue >= 0) return 0;
return minValue;
}
String msg = null;
int value = 0;
while (true) {
try {
value = parser.parse(text).intValue();
if (value >= minValue && value <= maxValue) break;
msg = "Value is outside the specified range";
} catch (ParseException ex) {
msg = "Illegal integer format";
}
if (exceptionOnError) {
throw new ErrorException(msg);
} else {
String prompt = "Enter an integer";
if (minValue != Integer.MIN_VALUE) {
if (maxValue != Integer.MAX_VALUE) {
prompt += " between " + minValue + " and " + maxValue;
} else {
prompt += " greater than " + minValue;
}
} else {
if (maxValue != Integer.MAX_VALUE) {
prompt += " less than " + maxValue;
}
}
if (dialog == null) dialog = new IODialog(this);
value = dialog.readInt(prompt, minValue, maxValue);
break;
}
}
setValue(value);
return value;
}
/* Method: setValue(n) */
/**
* Sets the value of a field.
*
* Example: field.setValue(n);
* @param n The value to be stored in the field
*/
public void setValue(int n) {
setText((formatter == null) ? defaultFormat(n) : formatter.format(n));
}
/* Method: getFormat() */
/**
* Returns the format currently in use for this field, or
* null
if no format has been set.
*
* Example: String format = field.getFormat();
* @return The format for this field
*/
public String getFormat() {
return formatString;
}
/* Method: setFormat(format) */
/**
* Sets the format used for the field. The structure of the
* format string is described in the comments for the DecimalFormat
* class.
*
* Example: field.setFormat(format);
* @param format The format to use for the field
*/
public void setFormat(String format) {
String contents = getText().trim();
int value = 0;
if (contents.length() != 0) {
try {
value = parser.parse(contents).intValue();
} catch (ParseException ex) {
throw new ErrorException(ex);
}
}
formatString = format;
if (format == null) {
formatter = null;
parser = NumberFormat.getNumberInstance(Locale.US);
} else {
formatter = (format.length() == 0) ? new DecimalFormat() : new DecimalFormat(format);
parser = formatter;
}
if (contents.length() != 0) {
setValue(value);
}
}
/* Method: setExceptionOnError(flag) */
/**
* Sets the error-handling mode of this interactor as specified by the flag
* parameter. If flag
is false
(which is the default),
* calling getValue
on this interactor displays
* a dialog that gives the user a chance to retry after erroneous input. If this
* value is set to true
, illegal input raises an
* ErrorException
instead.
*
* Example: field.setExceptionOnError(flag);
* @param flag false
to retry on errors; true
to raise an exception
*/
public void setExceptionOnError(boolean flag) {
exceptionOnError = flag;
}
/* Method: getExceptionOnError() */
/**
* Returns the state of the error-handling flag.
*
* Example: boolean flag = console.getExceptionOnError();
* @return The current setting of the error-handling mode (false
to retry
* on errors; true
to raise an exception)
*/
public boolean getExceptionOnError() {
return exceptionOnError;
}
/* Override method: getPreferredSize() */
/**
* Overrides the standard definition to impose a target size.
*
*/
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
return new Dimension(Math.max(MINIMUM_WIDTH, size.width),
Math.max(MINIMUM_HEIGHT, size.height));
}
/* Private method: defaultFormat(n) */
/**
* This method formats the number if the formatter is null
.
* The only special case that applies occurs if the output is larger than
* the field, in which case the entire display is replaced by number signs.
*/
private String defaultFormat(int n) {
String str = "" + n;
int availableSpace = getSize().width - 2 * PIXEL_MARGIN;
FontMetrics fm = getFontMetrics(getFont());
if (fm.stringWidth(str) > availableSpace) {
str = "";
while (fm.stringWidth(str + "#") <= availableSpace) {
str += "#";
}
}
return str;
}
/* Private constants */
private static final int MINIMUM_WIDTH = 60;
private static final int MINIMUM_HEIGHT = 22;
private static final int PIXEL_MARGIN = 2;
/* Private instance variables */
private boolean exceptionOnError;
private int minValue;
private int maxValue;
private String formatString;
private DecimalFormat formatter;
private NumberFormat parser;
private IODialog dialog;
/* Serial version UID */
/**
* The serialization code for this class. This value should be incremented
* whenever you change the structure of this class in an incompatible way,
* typically by adding a new instance variable.
*/
static final long serialVersionUID = 1L;
}