javafxtextfieldillegalstateexceptionchangelistener

JavaFX TextField listener gives java.lang.IllegalArgumentException: The start must be <= the end


So I am writing a javafx program to manipulate the individual bits in a byte. I have a textfield for each bit. I want to implement a changelistener on the textfields so one cannot enter anything but a 0 or a 1. It works fine if the field is empty and the user tries to enter a letter, but if there is already a 0 or 1 in it it throws an exception and I dont understand why.

Here is my code:

public class Task03Controller implements Initializable {
    @FXML private TextField zeroTextField, oneTextField, twoTextField, threeTextField,
                            fourTextField, fiveTextField, sixTextField, sevenTextField;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        zeroTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            if(!zeroTextField.getText().equals("0") && !zeroTextField.getText().equals("1"))
                zeroTextField.clear();
           else if(zeroTextField.getText().length() > 1)
               zeroTextField.setText(zeroTextField.getText().substring(0, 0));
        });
    }
}

Solution

  • Using the same idea as the duplicate. You need to define a regular expression that matches binary numbers.

    I am using "\\b[01]+\\b" to define binary numbers and "" to define an empty TextField.

    MCVE

    import java.util.function.UnaryOperator;
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.control.TextFormatter.Change;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
    public class TestingGroundsTwo extends Application
    {
        public static void main(String[] args)
        {
            launch(args);
        }
    
        @Override
        public void start(Stage stage)
        {
            UnaryOperator<Change> binaryFilter = change -> {
                String newText = change.getControlNewText();
                if (newText.matches("\\b[01]+\\b") || newText.matches("")) {
                    return change;
                }
                return null;
            };
            TextField textField = new TextField();
            textField.setTextFormatter(new TextFormatter<>(binaryFilter));
    
            stage.setTitle("Hello World!");
            Scene scene = new Scene(new StackPane(textField), 750, 125);
            scene.setFill(Color.GHOSTWHITE);
            stage.setScene(scene);
            stage.show();
        }
    }