I need a text field very similar in behavior to Gxt's NumberField. Unfortunately I am not using Gxt in my application and GWT 2.0 does not have a Numeric text field implementation as yet.
So that currently leaves me with an option to simulate a NumberField by filtering out non-numeric keystrokes using a keyboardHandler.
Is this the the best way to approach the problem? Does anyone here have a better solution/approach in mind?
Thanks in advance :)
Here you can find the code that I use in one of my classes. The features are much more limited that those of GXT, but should put you in the proper track.
It's a really basic widget, but does what I need to.
public class ValueTextBox extends TextBox {
private int min = 0;
private int max = 100;
private boolean minConstrained = true;
private boolean maxConstrained = true;
private int minDigits = 1;
private int step = 1;
private KeyUpHandler keyUpHandler = new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
if (isReadOnly() || !isEnabled()) {
return;
}
int keyCode = event.getNativeEvent().getKeyCode();
boolean processed = false;
switch (keyCode) {
case KeyCodes.KEY_LEFT:
case KeyCodes.KEY_RIGHT:
case KeyCodes.KEY_BACKSPACE:
case KeyCodes.KEY_DELETE:
case KeyCodes.KEY_TAB:
if (getText().isEmpty()) {
setValue(formatValue(min));
}
return;
case KeyCodes.KEY_UP:
if (step != 0) {
increaseValue();
processed = true;
}
break;
case KeyCodes.KEY_DOWN:
if (step != 0) {
decreaseValue();
processed = true;
}
break;
}
if (processed) {
cancelKey();
}
}
};
private KeyPressHandler keyPressHandler = new KeyPressHandler() {
@Override
public void onKeyPress(KeyPressEvent event) {
if (isReadOnly() || !isEnabled()) {
return;
}
int keyCode = event.getNativeEvent().getKeyCode();
switch (keyCode) {
case KeyCodes.KEY_LEFT:
case KeyCodes.KEY_RIGHT:
case KeyCodes.KEY_BACKSPACE:
case KeyCodes.KEY_DELETE:
case KeyCodes.KEY_TAB:
case KeyCodes.KEY_UP:
case KeyCodes.KEY_DOWN:
return;
}
int index = getCursorPos();
String previousText = getText();
String newText;
if (getSelectionLength() > 0) {
newText = previousText.substring(0, getCursorPos())
+ event.getCharCode()
+ previousText.substring(getCursorPos()
+ getSelectionLength(), previousText.length());
} else {
newText = previousText.substring(0, index)
+ event.getCharCode()
+ previousText.substring(index, previousText.length());
}
cancelKey();
setValue(newText, true);
}
};
public ValueTextBox(int value) {
this(value, 0, 100);
}
public ValueTextBox(int value, int min, int max) {
this(value, min, max, true);
}
public ValueTextBox(int value, int min, int max, boolean constrained) {
this(value, min, max, constrained, constrained);
}
public ValueTextBox(int value, int min, int max, boolean minConstrained,
boolean maxConstrained) {
super();
addKeyPressHandler(keyPressHandler);
addKeyUpHandler(keyUpHandler);
this.min = min;
this.max = max;
this.minConstrained = minConstrained;
this.maxConstrained = maxConstrained;
setValue(formatValue(value), false);
setTextAlignment(TextBoxBase.ALIGN_CENTER);
setStyleName(Resources.INSTANCE.css().fwFormEntry());
}
public void setMinDigits(int minDigits) {
if (minDigits > 0) {
this.minDigits = minDigits;
String value = getText();
long newValue = parseValue(value);
setText(formatValue(newValue));
}
}
public void setSteps(int step) {
this.step = step;
}
protected void increaseValue() {
if (step != 0) {
String value = getText();
long newValue = parseValue(value);
newValue += step;
if (maxConstrained && (newValue > max)) {
return;
}
setValue(formatValue(newValue));
}
}
protected void decreaseValue() {
if (step != 0) {
String value = getText();
long newValue = parseValue(value);
newValue -= step;
if (minConstrained && (newValue < min)) {
return;
}
setValue(formatValue(newValue));
}
}
/**
* @param value
* the value to format
* @return the formatted value
*/
protected String formatValue(long value) {
String newValue = String.valueOf(value);
if (minDigits > newValue.length()) {
String leading = StringUtils.repeat("0", (minDigits - newValue
.length()));
newValue = leading + newValue;
}
return newValue;
}
@Override
public void setValue(String value) {
setValue(value, false);
}
@Override
public void setValue(String value, boolean fireEvents) {
try {
long newValue = parseValue(value);
if ((maxConstrained && (newValue > max))
|| (minConstrained && (newValue < min))) {
return;
}
String prevText = getValue();
super.setText(formatValue(newValue));
if (fireEvents) {
ValueChangeEvent.fireIfNotEqual(this, getValue(), prevText);
}
} catch (Exception ex) {
// Do Nothing
System.out.println(ex.getMessage());
}
}
/**
* @param value
* the value to parse
* @return the parsed value
*/
protected long parseValue(String value) {
return Long.valueOf(value);
}
}
Update: The code is available in https://github.com/ctasada/GWT-Eureka