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
Post a Comment