Search code examples
javafxjtextfield

JavaFX : TextField max and min value by listener


I need to limit interval of the text property of a text field

int maxLength = 64;
    int minLength = 0;
    txtSeuil.textProperty().addListener((v, oldValue, newValue) -> {
        if (!newValue.matches("\\d*")) {
            txtSeuil.setText(newValue.replaceAll("[^\\d*{1,2}]", ""));
            if (txtSeuil.getText().length() > maxLength || txtSeuil.getText().length() < minLength) {
                String s = txtSeuil.getText().substring(0, maxLength);
                txtSeuil.setText(s);
            }
        }

    });

the field does accept only numbers but any number, not just the interval values


Solution

  • If I have understood correctly, you're trying to implement a number field that only allows values within the interval [0, 64]. According to this answer, TextFormatter is the recommended way to accomplish such a functionality. Have a look at this MWE which should solve your problem:

    public class RestrictedNumberFieldDemo extends Application {
    
        public static void main(String[] args) {
            launch();
        }
    
        @Override
        public void start(Stage primaryStage) {
            TextField numField = new TextField();
            numField.setTextFormatter(new TextFormatter<Integer>(change -> {
                // Deletion should always be possible.
                if (change.isDeleted()) {
                    return change;
                }
    
                // How would the text look like after the change?
                String txt = change.getControlNewText();
    
                // There shouldn't be leading zeros.
                if (txt.matches("0\\d+")) {
                    return null;
                }
    
                // Try parsing and check if the result is in [0, 64].
                try {
                    int n = Integer.parseInt(txt);
                    return 0 <= n && n <= 64 ? change : null;
                } catch (NumberFormatException e) {
                    return null;
                }
            }));
    
            primaryStage.setScene(new Scene(numField));
            primaryStage.show();
        }
    
    }