Issue
I am trying to apply a regex pattern on my TextField so that the user can only type characters, numbers and spaces however I don't want there to be any spaces or numbers at the start. (I can't just remove the spaces after entry). I use the Regex and code below to achieve that however once the first character is entered it cannot be removed with backspace and remains there permanently whilst any other character that isn't in the first position can be backspaced. How can I fix this problem and ensure the entire TextField can be backspaced?
I am using javaFX 8.
import java.io.File;
import java.util.function.UnaryOperator;
import java.util.regex.Pattern;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class test extends Application{
@Override
public void start(Stage primaryStage) {
try{
TextField user = new TextField();
Pattern pattern = Pattern.compile("[a-zA-Z][a-zA-Z0-9 ]*");
UnaryOperator<TextFormatter.Change> filter = string -> {
if (pattern.matcher(string.getControlNewText()).matches()) {
return string ;
} else {
return null ;
}
};
TextFormatter<String> formatter = new TextFormatter<>(filter );
user.setTextFormatter(formatter);
//username submit button
Button submitButton = new Button("Submit");
//submit action for button
Label userPrompt = new Label("Enter name");
Stage stage = new Stage();
stage.setTitle("Username Entry");
VBox userEntry = new VBox(userPrompt,user , submitButton);
Scene scene1 = new Scene((userEntry),400,300);
stage.setScene(scene1);
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Solution
Check for an empty string, or change your regular expression to be capable of matching an empty string.
This regular expression:
Pattern.compile("[a-zA-Z0][a-zA-Z0-9 ]*");
means “exactly one alphabetic character (or zero), followed by any number of spaces or alphanumeric characters.”
You can place a |
at the start or end of the expression to match an empty string:
Pattern.compile("|[a-zA-Z0][a-zA-Z0-9 ]*");
Another approach is to check for an empty string explicitly:
Pattern pattern = Pattern.compile("[a-zA-Z0][a-zA-Z0-9 ]*");
UnaryOperator<TextFormatter.Change> filter = string -> {
String newText = string.getControlNewText();
if (newText.isEmpty() || pattern.matcher(newText).matches()) {
return string;
} else {
return null;
}
};
You say “however I don't want there to be any spaces or numbers at the start” but your expression allows zero (0
) as an initial character. If you really don’t want any numbers at the start, remove that zero by changing this:
Pattern.compile("[a-zA-Z0][a-zA-Z0-9 ]*");
to this:
Pattern.compile("[a-zA-Z][a-zA-Z0-9 ]*");
Answered By - VGR
Answer Checked By - Timothy Miller (JavaFixing Admin)