속성에 추가 된 수신기에 액세스 할 수있는 방법이 없습니다.
ChangeListener<String> textFieldListener = (observable, oldValue, newValue) -> {
if (!newValue.matches("\\d*")) {
textField.setText(newValue.replaceAll("[^\\d]", ""));
}
if (newValue.isEmpty())
textField.setText("0");
};
textField.textProperty().addListener(textFieldListener);
textFieldListener.changed(null, null, textField.getText());
또는 아마도 더 자연스럽게, 단지 다른 방법으로 실제 기능을 이동 : 분명히 당신은 단지에 대한 참조를 유지할 수
textField.textProperty().addListener((observable, oldValue, newValue) -> vetoTextFieldChanges());
vetoTextFieldChanges();
// ...
private void vetoTextFieldChanges() {
String newText = textField.getText();
if (!newText.matches("\\d*")) {
textField.setText(newText.replaceAll("[^\\d]", ""));
}
if (newText.isEmpty())
textField.setText("0");
}
주 그 변화를보고 전체 접근 방법과 그런 다음 비즈니스 논리와 일치하지 않는 경우 수정하면 만족스럽지 않습니다. 예를 들어, 속성에 등록 된 다른 리스너가있는 경우 텍스트의 중간 (잘못된) 값이 표시 될 수 있습니다. 이를 수행하는 방법은 TextFormatter
을 사용하는 것입니다. TextFormatter
은 모두 이 업데이트되기 전에 텍스트에 요청 된 변경을 거부하고 텍스트를 적절한 값으로 변환하도록 허용합니다. 따라서 귀하의 경우에 당신은 할 수 :
UnaryOperator<TextFormatter.Change> filter = change -> {
// remove any non-digit characters from inserted text:
if (! change.getText().matches("\\d*")) {
change.setText(change.getText().replaceAll("[^\\d]", ""));
}
// if new text is empty, replace all text with "0":
if (change.getControlNewText().isEmpty()) {
change.setRange(0, change.getControlText().length());
change.setText("0");
}
return change ;
};
TextFormatter<Integer> formatter = new TextFormatter<Integer>(new IntegerStringConverter(), 0, filter);
textField.setTextFormatter(formatter);
이제 직접 포맷터의 value
특성을 통해 (숫자) 값을 얻을 수있는 포맷을 사용, 등 모델에 바인드 할 수 있습니다
// assume model is a data model and valueProperty() returns a Property<Integer>:
formatter.valueProperty().bindBidirectional(model.valueProperty());
이 바인딩은 모델이 변경 될 때 포맷터 (결과적으로 텍스트 필드)를 업데이트하고 모델 값에 따라 초기화하여 원래의 질문에 대한 해결책을 제공한다는 점에 유의하십시오.
응용 프로그램을 시작할 때 어떤 텍스트가 있습니까? –
비었지만 TextField는 많은 경우 중 하나입니다. 또 다른 경우는 TableView에서 선택한 항목에 따라 속성을 비활성화하려는 Button입니다. –
하지만 비어있는 경우 리스너는이를 ""0 "'으로 변경합니다. 그럼 왜 그것을 "0"'으로 초기화하지 않겠습니까? 다른 컨트롤과 마찬가지로 : 상태를 사용자의 요구 사항과 일치하도록 초기화하십시오. ('Button'을 사용하면'button.disableProperty(). bind (tableView.getSelectionModel(). selectedItemProperty(). isNull());') 대신 바인딩을 사용할 수 있습니다. –