I am trying to create a numeric TextField for Integers by using the TextFormatter of JavaFX 8.
Solution with UnaryOperator:
UnaryOperator<Change> integerFilter = change -> {
String input = change.getText();
if (input.matches("[0-9]*")) {
return change;
}
return null;
};
myNumericField.setTextFormatter(new TextFormatter<String>(integerFilter));
Solution with IntegerStringConverter:
myNumericField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter()));
Both solutions have their own problems. With the UnaryOperator, I can only enter digits from 0 to 9 like intended, but I also need to enter negative values like "-512", where the sign is only allowed at the first position. Also I don't want numbers like "00016" which is still possible.
The IntegerStringConverter method works way better: Every invalid number like "-16-123" is not accepted and numbers like "0123" get converted to "123". But the conversion only happens when the text is commited (via pressing enter) or when the TextField loses its focus.
Is there a way to enforce the conversion of the second method with the IntegerStringConverter every time the value of the TextField is updated?
The converter is different to the filter: the converter specifies how to convert the text to a value, and the filter filters changes the user may make. It sounds like here you want both, but you want the filter to more accurately filter the changes that are allowed.
I usually find it easiest to check the new value of the text if the change were accepted. You want to optionally have a
-
, followed by1-9
with any number of digits after it. It's important to allow an empty string, else the user won't be able to delete everything.So you probably need something like
You can even add more functionality to the filter to let it process
-
in a smarter way, e.g.This will let the user press
-
at any point and it will toggle the sign of the integer.SSCCE: