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 jtextfields 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 documentlisteners:

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

Popular posts from this blog

amazon web services - S3 Pre-signed POST validate file type? -

c# - Check Keyboard Input Winforms -