java - TextField onEdit listener -


i trying use textfield in javafx. scenario: have list view populated specific objects , edit button edit object associated list cell of list view. when click on edit button redirects me pane editing feature can edit name of object , save using save button. have put validation on save button make enable , disable. if edit name in text field should enable save button otherwise should remains disabled. have tried using different methods on text fields below.

textfield.textporperty.addlistener(listener -> {         //logic enable disable save button }); 

as using list view, listener gives me old value edited object not satisfy condition. can not use

textfield.focusedproperty().addlistener((observablevalue, oldvalue, newvalue) -> {}); 

as not give me expected behavior.

can me solve issue?

you need implement additional logic decides whether or not change textproperty should change enablement state of button. requires:

  • a reference initial value (on setting text input, f.i. on changes selection in list)
  • a boolean property keeps enablement state (below it's called buffering)
  • a listener textfield updates enablement state needed

below simplified example - started - extracts basics dedicated class named bufferedtextinput. buffering changed internally on:

  • set false if "subject" value set or change committed/discarded
  • set true once on being notified on first change of textfield

more complex logic (like not buffering on detecting change original value) can implemented needed.

/**  * bind disable property of commit/cancel button actual change.   * http://stackoverflow.com/q/29935643/203657  */ public class manualbufferingdemo extends application {      private parent getcontent() {         observablelist<person> persons = fxcollections.observablelist(person.persons(),                  person -> new observable[] {person.lastnameproperty()});         listview<person> listview = new listview<>(persons);          textfield lastname = new textfield();         consumer<string> committer = text -> system.out.println("committing: " + text);         bufferedtextinput buffer = new bufferedtextinput(lastname, committer);         button save = new button("save");         save.setonaction(e -> {             buffer.commit();         });         save.disableproperty().bind(bindings.not(buffer.bufferingproperty()));         button cancel = new button("cancel");         cancel.setonaction(e -> {            buffer.flush();          });         listview.getselectionmodel().selecteditemproperty().addlistener((source, old, current) -> {             buffer.setsubject(current.lastnameproperty());         });         cancel.disableproperty().bind(bindings.not(buffer.bufferingproperty()));         vbox content = new vbox(listview, lastname, save, cancel);         return content;     }       public static class bufferedtextinput {          private readonlybooleanwrapper buffering;         private stringproperty value;         private textfield input;         private consumer<string> committer;          public bufferedtextinput(textfield input, consumer<string> committer) {             buffering = new readonlybooleanwrapper(this, "buffering", false);             value = new simplestringproperty(this, "");             this.input = input;             this.committer = committer;             input.textproperty().addlistener((source, old, current) -> {                 updatestate(old, current);             });             input.setonaction(e -> commit());         }          private void updatestate(string old, string current) {             if (isbuffering()) return;             if (value.get().equals(current)) return;             setbuffering(true);         }          public void setsubject(stringproperty value) {             this.value = value;             input.settext(value.get());             setbuffering(false);         }          public void commit() {             committer.accept(input.gettext());             this.value.set(input.gettext());             setbuffering(false);         }          public void flush() {             input.settext(value.get());             setbuffering(false);         }          public boolean isbuffering() {             return buffering.get();         }          public readonlybooleanproperty bufferingproperty() {             return buffering.getreadonlyproperty();         }          private void setbuffering(boolean buffer) {             buffering.set(buffer);         }     }      @override     public void start(stage primarystage) throws exception {         primarystage.setscene(new scene(getcontent()));         primarystage.show();     }      public static void main(string[] args) {         launch(args);     } } 

for production use, such direct coupling between view , model (f.i. when needing buffering complete form) isn't enough, further separation might needed. see bufferedobjectproperty , usage in fx adaption of infamous albummanager example (very crude)


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -