JavaFX:侦听器的TextField最大值和最小值

时间:2017-01-06 20:07:56

标签: javafx jtextfield

我需要限制文本字段的文本属性的间隔

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);
            }
        }

    });

该字段仅接受数字,但只接受任何数字,而不仅仅是间隔值

3 个答案:

答案 0 :(得分:2)

要解决您的问题,您可以为TextFormatter实施自定义Filter。它只允许输入数字并限制字符串的长度。这是一个片段,展示了它是如何工作的:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.stage.Stage;

public class Main5 extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        TextField textField = new TextField();
        textField.setTextFormatter(new TextFormatter<Integer>(change -> {
            if (!change.getText().isEmpty()) {
                return change.getText().matches("\\d+") && change.getControlNewText().length() <= 5 ? change : null;
            }

            return change;
        }));

        primaryStage.setScene(new Scene(textField));
        primaryStage.show();
    }
}

答案 1 :(得分:1)

如果我理解正确,那么您正在尝试实现一个只允许区间[0,64]内的值的数字字段。根据{{​​3}},this answer是完成此类功能的推荐方法。看一下应该解决问题的TextFormatter

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();
    }

}

答案 2 :(得分:0)

你的问题是:

如果正则表达式匹配,则不会进行长度检查。但是文本可以是数字序列是长。

您需要彼此独立地进行这些检查。

此外,您在某些情况下设置新值,再次触发相同的检查。当然,它们会导致String被评估为有效输入,但是你可以通过在存储的ChangeListener中引入一个字段来阻止再次检查,无论是否正在执行监听器:

txtSeuil.textProperty().addListener(new ChangeListener<String>() {

    private boolean validating = false;

    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        if (!validating) {
            validating = true;
            String newText = newValue;
            boolean modify = false;
            if (!newValue.matches("\\d*")) {
                newText = newValue.replaceAll("[^\\d*{1,2}]", "");
                modify = true;
            }
            if (newText.length() > maxLength || newText.length() < minLength) {
                newText = newText.substring(0, maxLength);
                modify = true;
            }
            if (modify) {
                txtSeuil.setText(newText);
            }
            validating = false;
        }
    }
});