JavaFX: Run ChangeListener -


ho can run change method inside changelistener in initialization. since run when changes happen. example have textfield want set it's value 0 when it's empty, , this:

textfield.textproperty().addlistener(new changelistener<string>() {         @override         public void changed(observablevalue<? extends string> observable, string oldvalue, string newvalue) {             if (!newvalue.matches("\\d*")) {                 textfield.settext(newvalue.replaceall("[^\\d]", ""));             }              if (newvalue.isempty())                 textfield.settext("0");          }     }); 

but @ start of application changed method not called. how work around issue?

there's no way access listener added property. keep reference it:

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()); 

or, perhaps more naturally, move actual functionality different method:

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"); } 

note whole approach of watching changes , modifying them if inconsistent business logic not satisfactory. example, if have other listeners registered property, may see intermediate (invalid) values of text. supported way use textformatter. textformatter both allows veto changes requested text, before textproperty() updated, , convert text appropriate value. in case do:

unaryoperator<textformatter.change> filter = change -> {      // remove non-digit characters inserted text:     if (! change.gettext().matches("\\d*")) {         change.settext(change.gettext().replaceall("[^\\d]", ""));     }      // if new text empty, replace text "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); 

now can use formatter (numeric) values directly via formatter's value property, , bind them model, etc:

// assume model data model , valueproperty() returns property<integer>: formatter.valueproperty().bindbidirectional(model.valueproperty()); 

note binding both update formatter (and consequently text field) when model changes, , initialize depending on model value (thus providing solution original question).


Comments

Popular posts from this blog

python - How to insert QWidgets in the middle of a Layout? -

python - serve multiple gunicorn django instances under nginx ubuntu -

module - Prestashop displayPaymentReturn hook url -