Как ограничить количество символов текстового поля javafx
Im использует FXML для установки моей формы, но мне нужно установить предел символов в текстовых полях. Как я могу сделать это ?
6 ответов
вот мое решение для ограничения длины текстового поля. Я бы не рекомендовал решения, которые используют прослушиватель (по свойству text или по свойству length), они не ведут себя правильно во всех ситуациях (для того, что я видел). Я создаю текст ввода HTML с максимальной длиной и сравниваю его с моим текстовым полем в JavaFX. У меня было такое же поведение с операциями вставки (Ctrl + V), отменой операций (Ctrl + Z) в обоих случаях. Цель здесь-проверить, является ли текст допустимым перед изменением объект TextField. Мы могли бы использовать аналогичный подход для числового текстового поля.
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
вы не можете напрямую установить ограничение на количество символов. Но вы можете добавить listener
to 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();
}
}
еще одно элегантное решение
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 - минимальное и максимальное количество символов. + возможность установить шаблон ввода текста
Это очень простое решение, которое, кажется, работает для меня.
textfield.setOnKeyTyped(event ->{
int maxCharacters = 5;
if(tfInput.getText().length() > maxCharacters) event.consume();
});
Я использую простой вызов ChangeListener, где я тестирую условие для выполнения остановок.
textFild.addListener((observable, oldValue, newValue) -> {
if (newValue.length() == MAX_SIZE) {
textField.setText(oldValue);
}
});
Это лучший способ выполнить работу с общим текстовым полем:
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); } } }); }
работает отлично, за исключением этой ошибки отмены.