java - JTextFields and DocumentListeners -
i want 2 textfields (from , b) sharing same content user inputs on of them. can make 1 mirror other (b mirrors a) or opposite (a mirrors b). when keep both documentlisteners execution starts throw exceptions.
according oracle's docs can't use documentlistener mutate content of document within listener itself. find weird since did in first case (b mirrors a) or opposite case. anyway code still "works" exception thrown every 2 events triggered.
keylisteners not reliable particular case , refuse use buttons because real-time documentlistener gives.
any suggestions?
here's code:
import java.awt.gridbagconstraints; import java.awt.gridbaglayout; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jtextfield; import javax.swing.event.documentevent; import javax.swing.event.documentlistener; public class mirror { private jtextfield oritext; private jtextfield mirrortext; private static int debugcounter; //counts times event triggered. public static void main(string[] args) { mirror gui = new mirror(); gui.build(); } public void build(){ jframe frame = new jframe(); jpanel panel = new jpanel(); panel.setlayout(new gridbaglayout()); gridbagconstraints c = new gridbagconstraints(); frame.getcontentpane().add(panel); frame.setdefaultcloseoperation(jframe.exit_on_close); c.gridx = 0; c.gridy = 0; jlabel original = new jlabel("original"); panel.add(original, c); c.gridy = 1; oritext = new jtextfield(10); panel.add(oritext,c); c.gridy = 2; jlabel mirror = new jlabel("mirror"); panel.add(mirror, c); c.gridy = 3; mirrortext = new jtextfield(10); panel.add(mirrortext, c); mirrortext.getdocument().adddocumentlistener(new mydocumentlistenerii()); // comment line see 1st case (b mirrors a) oritext.getdocument().adddocumentlistener(new mydocumentlistener()); // comment line see 2nd case (a mirrors b) frame.pack(); frame.setvisible(true); } class mydocumentlistener implements documentlistener{ @override public void changedupdate(documentevent e) { //does nothing. } @override public void insertupdate(documentevent e) { mirror(); } @override public void removeupdate(documentevent e) { mirror(); } } class mydocumentlistenerii implements documentlistener{ @override public void changedupdate(documentevent e) { // nothing. } @override public void insertupdate(documentevent e) { mirror1(); } @override public void removeupdate(documentevent e) { mirror1(); } } public void mirror(){ if (!oritext.gettext().equals(mirrortext.gettext())){ //without each event trigger other in sort of paradoxical cycle. mirrortext.settext(oritext.gettext()); debugcounter++; system.out.println(debugcounter+" events triggered"); } } public void mirror1(){ if (!mirrortext.gettext().equals(oritext.gettext())){ oritext.settext(mirrortext.gettext()); debugcounter++; system.out.println(debugcounter+" events triggered"); } } }
the problem you're having since both jtextfield
s need sync, each field's documentlistener
needs update other field. however, update causes other documentlistener
attempt update first field, causing thrown illegalstateexception
, since attempting modify field while documentlistener
executing.
the solution block calls settext(string)
when documentlistener
being executed field. can done boolean
variables. below code 1 of documentlistener
s:
textfielda.getdocument().adddocumentlistener(new documentlistener() { @override public void removeupdate (documentevent e) { blocka = true; if (!blockb) textfieldb.settext(textfielda.gettext()); blocka = false; } @override public void insertupdate (documentevent e) { blocka = true; if (!blockb) textfieldb.settext(textfielda.gettext()); blocka = false; } @override public void changedupdate (documentevent e) { blocka = true; if (!blockb) textfieldb.settext(textfielda.gettext()); blocka = false; } });
where blocka
, blockb
boolean
instance fields (or possibly final
variables in method). now, when method fires in textfielda
's documentlistener
, flag set indicate not use textfielda.settext(string)
. we, see how textfieldb.settext(string)
blocked when blockb
set. documentlistener
textfieldb
looks same.
now, textfielda
won't set during call inside documentlistener
, same other field. such call redundant anyway: text of each field same @ point.
Comments
Post a Comment