On the Internet, I found very useful class, using which I can restrict TextField. I encountered a problem, where my TextField can contain only one \'.\' character. I suspect
There are various versions of the regex, depending on exactly what you want to support. Note that you don't only want to match valid numbers, but also partial entries, because the user has to be able to edit this. So, for example, an empty string is not a valid number, but you certainly want the user to be able to delete everything that's there while they are editing; similarly you want to allow "0."
, etc.
So you probably want something like
Optional minus sign, followed by either any number of digits, or at least one digit, a period (.
), and any number of digits.
The regex for this could be -?((\\d*)|(\\d+\.\\d*))
. There are probably other ways to do this, some of them perhaps more efficient. And if you want to support exponential forms ("1.3e12"
) it gets more complex.
To use this with a TextField
, the recommended way is to use a TextFormatter. The TextFormatter
consists of two things: a converter to convert between the text and the value it represents (a Double
in your case: you can just use the built-in DoubleStringConverter
), and vice versa, and then a filter. The filter is implemented as a function that takes a TextFormatter.Change
object and returns an object of the same type. Typically you either leave the Change
object as it is and return it (to accept the Change
"as is"), or modify it somehow. It is also legal to return null
to represent "no change". So in your simple case here, just examine the new proposed text, see if it matches the regular expression, return the change "as is" if it matches and return null
otherwise.
Example:
import java.util.regex.Pattern;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.converter.DoubleStringConverter;
public class NumericTextFieldExample extends Application {
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
Pattern validDoubleText = Pattern.compile("-?((\\d*)|(\\d+\\.\\d*))");
TextFormatter textFormatter = new TextFormatter(new DoubleStringConverter(), 0.0,
change -> {
String newText = change.getControlNewText() ;
if (validDoubleText.matcher(newText).matches()) {
return change ;
} else return null ;
});
textField.setTextFormatter(textFormatter);
textFormatter.valueProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("New double value "+newValue);
});
StackPane root = new StackPane(textField);
root.setPadding(new Insets(24));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}