Reputation: 21
So, I'm pretty new to javafx and was trying to use the textfield to take in a string and then, using a try catch, convert the string to a double if possible. The only problem I'm having is that if I enter a decimal, ex 1000.56, the catch activates and my error label pops up saying that it can't take in a string. This is the relevant block of code, please assume I have all the proper imports and all the basic setup for the variables done.
//takes in the users input and trims spaces
holder[i] = txtFld.getText().trim();
while(run == false) {
try {
//attempts to parse the stripped text to a double
amt[i] = Double.parseDouble(holder[i]);
//allows the loop to break
run = true;
}catch(NumberFormatException ex) {
txtFld.setText("");
//tells the user about the error
grid.add(Err, 0, 3);
}
}
Upvotes: 0
Views: 1391
Reputation: 82461
You should not do loops like this in JavaFX for several reasons:
-1E3
. The only way your code would allow this input would be stepwise changing the text like this: "" -> "1" -> "-1" -> "-13" -> "-1E3"
The simplest fix would be to simply check on "submitting" the data. Alternatively listen to the TextField.text
property and display some indication of invalid input (e.g. some icon) but do not modify the text on every change.
There's some implementation already available that tries to parse the text on focus loss: 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();
}
For "submission" buttons simply validate the value from the event handler:
@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();
}
Upvotes: 2