NumberField.java
package no.ntnu.idatt1002.demo.view.components;
import java.util.function.IntConsumer;
/**
* NumberField. Allows the user to input a number into a text field.
*/
public class NumberField extends InputField {
// ---------------------------------------------//
// Fields //
// ---------------------------------------------//
static final String REGEX = "^[0-9]*$";
private Integer lastValidValue;
// ---------------------------------------------//
// Constructor //
// ---------------------------------------------//
/**
* Constructor.
*/
public NumberField() {
super();
}
/**
* Constructor with default value.
*
* @param value The default value.
*/
public NumberField(int value) {
super(String.valueOf(value));
this.lastValidValue = value;
}
/**
* Constructor with on change listener.
*
* @param listener The on change listener. Only called when the input is a valid
*/
public NumberField(IntConsumer listener) {
this(null, listener);
}
/**
* Constructor with default value and on change listener.
*
* @param value The default value.
* @param listener The on change listener. Only called when the input is a valid
*/
public NumberField(int value, IntConsumer listener) {
this(Integer.toString(value), listener);
this.lastValidValue = value;
}
private IntConsumer listener;
private NumberField(String value, IntConsumer listener) {
super(value);
this.listener = listener;
this.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
this.onSubmit(this.getText());
}
});
// Handle changing the field
this.setOnChange(
newValue -> {
// If the input is a valid number, set it as the last valid value
if (this.isNumber()) {
Integer parsedValue = Integer.parseInt(newValue);
this.lastValidValue = parsedValue;
listener.accept(parsedValue);
}
// Highlight the input if it is not a valid number
this.highlightWrongInput();
});
// Handle submitting the field
this.setOnSubmit(this::onSubmit);
}
private void onSubmit(String s) {
// If the input is zero, set it as promt text and clear the field
if (this.lastValidValue == 0) {
this.setPromptText(lastValidValue.toString());
this.setText("");
return;
}
// If the input is a valid number, set it as the last valid value
if (this.isNumber()) {
this.setText(this.lastValidValue.toString());
listener.accept(Integer.parseInt(s));
return;
}
// If the input is not a valid number, set the last valid value as the text
this.setText(this.lastValidValue.toString());
listener.accept(this.lastValidValue);
}
/**
* When called, checks if the input is a valid number and highlights the input
* field if it is not.
*/
private void highlightWrongInput() {
final String fieldErrorClassName = "text-field-error";
// Check if the input is a valid number
if (!this.isNumber()) {
// If the input already is highlighted, return
if (this.getStyleClass().contains(fieldErrorClassName)) {
return;
}
// Highlight the input field
this.getStyleClass().add(fieldErrorClassName);
return;
}
// Remove the highlight if the input is a valid number
this.getStyleClass().remove(fieldErrorClassName);
}
// ---------------------------------------------//
// Methods //
// ---------------------------------------------//
/**
* Check if the input is a valid number.
*
* @return True if the input is a valid number.
*/
public boolean isNumber() {
return this.getText().matches(REGEX);
}
/**
* Get the value of the number field.
*
* @return The value of the number field or null if the input is not a valid
* number.
*/
public Integer getValue() {
if (!this.isNumber()) {
return null;
}
return Integer.parseInt(this.getText());
}
}