如何限制javafx文本字段的字符数量

时间:2014-03-28 13:29:05

标签: javafx fxml

我使用FXML来设置表单,但我需要在textfields中设置字符数限制。我怎么能做到这一点?

8 个答案:

答案 0 :(得分:11)

您无法直接设置字符数限制。但您可以在文本字段的listener中添加lengthProperty()

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TextFieldLimit extends Application {
    private static final int LIMIT = 10;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage primaryStage) {

        final TextField textField = new TextField();
        textField.lengthProperty().addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> observable,
                    Number oldValue, Number newValue) {
                if (newValue.intValue() > oldValue.intValue()) {
                    // Check if the new character is greater than LIMIT
                    if (textField.getText().length() >= LIMIT) {

                        // if it's 11th character then just setText to previous
                        // one
                        textField.setText(textField.getText().substring(0, LIMIT));
                    }
                }
            }
        });

        VBox vbox = new VBox(20);
        vbox.getChildren().add(textField);

        Scene scene = new Scene(vbox, 400, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

答案 1 :(得分:3)

另一个优雅的解决方案

Pattern pattern = Pattern.compile(".{0,25}");
    TextFormatter formatter = new TextFormatter((UnaryOperator<TextFormatter.Change>) change -> {
        return pattern.matcher(change.getControlNewText()).matches() ? change : null;
    });

    textField.setTextFormatter(formatter);

其中0和25-最小和最大字符数。 +可以设置输入文字的模式

答案 2 :(得分:2)

这是我的限制文本字段长度的解决方案。 我不推荐使用监听器的解决方案(在文本属性或长度属性上),它们在所有情况下都不正常(对于我所看到的)。 我创建了一个具有最大长度的HTML输入文本,并将其与JavaFX中的文本字段进行比较。在两种情况下,我都使用粘贴操作(Ctrl + V),取消操作(Ctrl + Z)具有相同的行为。这里的目标是在修改文本字段之前检查文本是否有效。 我们可以对数字文本字段使用类似的方法。

import java.util.Objects;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.control.TextField;   

public class LimitedTextField extends TextField {

    private final IntegerProperty maxLength;

    public LimitedTextField() {
        super();
        this.maxLength = new SimpleIntegerProperty(-1);
    }

    public IntegerProperty maxLengthProperty() {
        return this.maxLength;
    }

    public final Integer getMaxLength() {
        return this.maxLength.getValue();
    }

    public final void setMaxLength(Integer maxLength) {
        Objects.requireNonNull(maxLength, "Max length cannot be null, -1 for no limit");
        this.maxLength.setValue(maxLength);
    }

    @Override
    public void replaceText(int start, int end, String insertedText) {
        if (this.getMaxLength() <= 0) {
            // Default behavior, in case of no max length
            super.replaceText(start, end, insertedText);
        }
        else {
            // Get the text in the textfield, before the user enters something
            String currentText = this.getText() == null ? "" : this.getText();

            // Compute the text that should normally be in the textfield now
            String finalText = currentText.substring(0, start) + insertedText + currentText.substring(end);

            // If the max length is not excedeed
            int numberOfexceedingCharacters = finalText.length() - this.getMaxLength();
            if (numberOfexceedingCharacters <= 0) {
                // Normal behavior
                super.replaceText(start, end, insertedText);
            }
            else {
                // Otherwise, cut the the text that was going to be inserted
                String cutInsertedText = insertedText.substring(
                        0, 
                        insertedText.length() - numberOfexceedingCharacters
                );

                // And replace this text
                super.replaceText(start, end, cutInsertedText);
            }
        }
    }
}

使用JavaFX 8和Java 8u45进行测试

答案 3 :(得分:1)

这是一个非常简单的解决方案,似乎对我有用。

textfield.setOnKeyTyped(event ->{
        int maxCharacters = 5;
        if(tfInput.getText().length() > maxCharacters) event.consume();
    });

答案 4 :(得分:1)

我使用对ChangeListener的简单调用,在那里我测试条件以执行停止。

textFild.addListener((observable, oldValue, newValue) -> {
    if (newValue.length() == MAX_SIZE) {
        textField.setText(oldValue);
    }
});

答案 5 :(得分:0)

这是在通用文本字段上完成工作的更好方法:

public static void addTextLimiter(final TextField tf, final int maxLength) {
    tf.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
            if (tf.getText().length() > maxLength) {
                String s = tf.getText().substring(0, maxLength);
                tf.setText(s);
            }
        }
    });
}

完美无缺,除了撤消错误。

答案 6 :(得分:0)

下面的 1-liner 正好可以做到,而 5 是 TextField tf 的限制:

tf.setTextFormatter(new TextFormatter<>(c -> c.getControlNewText().matches(".{0,5}") ? c : null));

答案 7 :(得分:-1)

这是一个运行良好的解决方案:

@FXML
void limitTextFields(KeyEvent event) {
    int maxLength = 5;
    TextField tf = (TextField) event.getSource();
    if (tf.getText().length() > maxLength) {
        tf.deletePreviousChar();
    }
}