#javafx
#javafx
Вопрос:
Я получил следующий код из окончательного руководства по современным Java-клиентам с JavaFX:
updateButton.disableProperty()
.bind(listView.getSelectionModel().selectedItemProperty().isNull()
.or(wordTextField.textProperty().isEmpty())
.or(definitionTextArea.textProperty().isEmpty()));
Я хотел бы изменить его, чтобы кнопка была отключена, если введенная строка frequencyTextField
не является неотрицательным целым числом. Я добавил термин к соединению, как показано:
updateButton.disableProperty()
.bind(listView.getSelectionModel().selectedItemProperty().isNull()
.or(isLegalFrequency(frequencyTextField.textProperty()).not())
.or(wordTextField.textProperty().isEmpty())
.or(definitionTextArea.textProperty().isEmpty()));
Хотя это, вероятно, не имеет значения, вот метод, который проверяет правильность:
private BooleanProperty isLegalFrequency(StringProperty sp) {
System.out.println("isLegalFrequency(" sp.get() ")");
try {
int value = Integer.parseInt(sp.get());
return new SimpleBooleanProperty(value >= 0);
} catch (NumberFormatException e) {
return new SimpleBooleanProperty(false);
}
}
Моя проблема в том, что кнопка всегда отключена. Я установил, что isLegalFrequency()
это вызывается только один раз, когда создается сцена. Это имеет смысл, поскольку я передаю frequencyTextField.textProperty()
, а не вызываю для него метод (который, предположительно, настраивает прослушиватель за кулисами).
Есть ли способ изменить программу без добавления явного прослушивателя, чтобы она вела себя так, как я хотел, или необходимо создать ChangeListener
on frequencyTextField.textProperty
?
Ответ №1:
В общем случае вы можете создать произвольный метод:
private Boolean validate() {
// arbitrary implementation here...
// in your case something like
if (listView.getSelectionModel().getSelectedItem() == null) return false ;
if (wordTextField.getText().isEmpty()) return false ;
if (definitionTextArea.getText().isEmpty()) return false ;
if (! isLegalFrequency(frequencyTextField.getText())) return false ;
return true ;
}
а затем выполните
updateButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! validate(),
listView.getSelectionModel().selectedItemProperty(),
frequencyTextField.textProperty(),
wordTextField.textProperty(),
definitionTextArea.textProperty()));
Параметрами createBooleanBinding()
метода являются a Callable<Boolean>
(т. Е. Метод, не принимающий параметров и возвращающий a Boolean
), За которым следует ноль или более экземпляров javafx.beans.Observable
(любое свойство или ObservableList
и т. Д. Будет работать). Вы должны включить здесь любое свойство (или другое наблюдаемое), которое должно вызвать пересчет disableProperty()
при его изменении.