プロパティに追加されたリスナーにアクセスする方法はありません。もちろん、あなたはそれへの参照を保持できます。
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
は、の前にのtextProperty()
が更新される前に、テキストに要求された変更を拒否し、テキストを適切な値に変換することができます。だから、あなたが行うことができ、あなたのケースで:
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は多くの場合の1つです。もう1つのケースは、TableViewで選択した項目に応じてプロパティを無効にするボタンです。 –
しかし空の場合、リスナーはそれを '' 0 ''に変更します。だから、なぜそれを '' 0 ''に初期化しないのですか?他のコントロールと同様に、それらの状態があなたの必要条件と一致するようにそれらを初期化するだけです。 ( 'Button'を使うと、代わりに' button.disableProperty()。bind(tableView.getSelectionModel()。selectedItemProperty()。isNull()); ')を使うことができます。 –