Вы не должны делать подобные циклы в JavaFX по нескольким причинам:
- Подобный цикл блокирует поток приложения.Это приводит к тому, что во время работы цикла входы не обрабатываются.
- Вы изменяете текст, даже если ввод не завершен.Рассмотрим сценарий, когда пользователь хочет ввести
-1E3
.Единственный способ, которым ваш код позволил бы этот ввод, - это поэтапное изменение текста следующим образом: "" -> "1" -> "-1" -> "-13" -> "-1E3"
Самое простое решение - просто проверить "отправку" данных.В качестве альтернативы можно прослушать свойство TextField.text
и отобразить некоторые указания на недопустимый ввод (например, значок), но не изменять текст при каждом изменении .
Существует некоторая уже доступная реализация, которая пытаетсяРазбор текста о потере фокуса: TextFormatter
:
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
TextFormatter<Double> formatter = new TextFormatter<>(new DoubleStringConverter(), 0d);
textField.setTextFormatter(formatter);
formatter.valueProperty().addListener((o, oldValue, newValue) -> System.out.println("value changed to " + newValue));
Button button = new Button("some other focusable element");
Scene scene = new Scene(new VBox(textField, button));
primaryStage.setScene(scene);
primaryStage.show();
}
Редактировать
Для кнопок «отправки» просто проверьте значение из обработчика событий:
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
Label textErrorLabel = new Label();
textErrorLabel.setTextFill(Color.RED);
HBox textBox = new HBox(10, textField, textErrorLabel);
textBox.setPrefWidth(300);
Button button = new Button("Submit");
button.setOnAction(evt -> {
boolean valid = true;
double value = 0;
try {
value = Double.parseDouble(textField.getText());
textErrorLabel.setText("");
textField.setStyle(null);
} catch (NumberFormatException ex) {
valid = false;
textErrorLabel.setText("erroneous input");
textField.setStyle("-fx-control-inner-background: red;");
}
// you could do more input validation here...
if (valid) {
System.out.println("successfully submitted "+ value);
}
});
Scene scene = new Scene(new VBox(textBox, button));
primaryStage.setScene(scene);
primaryStage.show();
}