[JavaFX] Spinner so einstellen, dass er nicht leer bleiben darf?
Wenn ich einen IntegerSpinner leer lasse und das Feld verlasse, bekomme ich eine NullPointerException, da logischer Weise nichts im Spinner steht.
Ich möchte den Spinner so einstellen, dass er mindestens eine Zahl beinhalten muss und maximal zweistellig sein darf. Ich meine damit nicht den Mindest- oder Maximalwert. Beispiel:
"" - leer; so ists falsch
"1" - nicht leer; so ists richtig
"11" - nicht leer; so ists richtig
"111" - mehr als zwei Zahlen; so ists falsch
Ich hatte schon mal sehr lange dieses Problem.
Nun möchte ich entweder auch eine eigene Fehlermeldung für diese NullPointerException haben (um z. B. .requestFocus() zu machen) oder einfach die Eingaben blockieren, wenn es, wie oben beschrieben, falsch gemacht wurde.
Mit regex kann ich schon mal einstellen, dass der Spinner eine rote Farbe bekommt (als Hinweis), wenn ein non-Integer eingegeben wurde oder zu wenige bzw. zu viele Zahlen eingegeben wurden:
if (!options_Spinner_StartInterval_seconds.getEditor().getText().matches("^-?\\d+$") || !options_Spinner_StartInterval_seconds.getEditor().getText().matches("^-?\\d.{0,2}$"))
options_Spinner_StartInterval_seconds.setStyle("-fx-focus-color: #f00;");
Wenn ich aber die Anzahl der Zahlen im Spinner überprüfe, kann ich kein
spinner.requestFocus();
machen - ich kann den Spinner trotzdem verlassen.
1 Antwort
Du könntest dich an das text-Property des Spinner-Textfeldes selbst hängen, um auf Wertänderungen zu reagieren. Das könnte ruhig mit in die Converter-Klasse, bspw. im Konstruktor oder in eine init-Methode, falls es bei einer anonymen Klasse bleiben soll. Allerdings würde ich Ersteres eher befürworten und den Converter in eine eigene Datei (als benannte Klasse) schreiben.
Beispiel:
public class SpinnerInputConverter extends StringConverter<Integer> {
public SpinnerInputConverter(TextField input, int min, int max) {
input.textProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null || newValue.isEmpty()) {
setTextValue(oldValue);
return;
}
int value;
try {
value = Integer.parseInt(newValue);
}
catch (NumberFormatException ex) {
setTextValue(oldValue);
}
if (value < min || value > max) {
setTextValue(oldValue);
}
});
}
private static void setTextValue(TextField field, int value) {
Platform.runLater(() -> field.setText(value));
}
// implement fromString, etc. ...
}
In diesem Fall würde bei falscher Werteingabe einfach nur der alte Wert bestehen bleiben. Wenn der schon invalid ist, wäre es besser, als Standardwert bspw. den Minimalwert des Spinners zu nutzen.
Für Fehlermeldungen auf der Programmoberfläche könntest du über den Konstruktor noch eine Referenz auf ein Feld hineinreichen, auf dem du Fehlermeldungen anzeigen möchtest.