Wednesday 15 June 2011

multithreading - java updating UI components from another thread -



multithreading - java updating UI components from another thread -

i found many answers question, still don't understand why application not throw exceptions. created new java form application in netbeans 8. form created , displayed in main method this:

public static void main(string args[]) { /* set nimbus , sense */ //<editor-fold defaultstate="collapsed" desc=" , sense setting code (optional) "> /* if nimbus (introduced in java se 6) not available, remain default , feel. * details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ seek { (javax.swing.uimanager.lookandfeelinfo info : javax.swing.uimanager.getinstalledlookandfeels()) { if ("nimbus".equals(info.getname())) { javax.swing.uimanager.setlookandfeel(info.getclassname()); break; } } } grab (classnotfoundexception ex) { java.util.logging.logger.getlogger(mainform.class.getname()).log(java.util.logging.level.severe, null, ex); } grab (instantiationexception ex) { java.util.logging.logger.getlogger(mainform.class.getname()).log(java.util.logging.level.severe, null, ex); } grab (illegalaccessexception ex) { java.util.logging.logger.getlogger(mainform.class.getname()).log(java.util.logging.level.severe, null, ex); } grab (javax.swing.unsupportedlookandfeelexception ex) { java.util.logging.logger.getlogger(mainform.class.getname()).log(java.util.logging.level.severe, null, ex); } //</editor-fold> /* create , display form */ java.awt.eventqueue.invokelater(new runnable() { public void run() { new mainform().setvisible(true); } }); }

so, new runnable creates new mainform , sets visible.

then, in code start new threads updates jbuttons , jtextfields. code below:

private void updateui() { updateuithread = new thread(() -> { while (true) { seek { jtfip.setenabled(!start && !autorec); jtfport.setenabled(!start && !autorec); jtfslaveid.setenabled(!start && !autorec); jtftimeout.setenabled(!start && !autorec); jtfreqinterval.setenabled(!start && !autorec); jcheckbox1.setenabled(!start && !autorec); jcbreconnect.setenabled(!start && !autorec); if (db != null) { if (!db.getisopen()) { jpbd.setbackground(color.red); jpbd.setforeground(color.white); jpbd.settext("er"); } else { jpbd.setbackground(color.green); jpbd.setforeground(color.black); jpbd.settext("ok "); } } else { jpbd.setbackground(color.red); jpbd.setforeground(color.white); jpbd.settext(" er "); } if (autorec){ jbtnconnect.settext("auto"); if (start && connected) { jbtnconnect.setforeground(color.black); jbtnconnect.setbackground(color.green); } else { jbtnconnect.setforeground(color.white); jbtnconnect.setbackground(color.red); } } else { if (start) { jbtnconnect.settext("disconnect"); jbtnconnect.setforeground(color.black); jbtnconnect.setbackground(color.green); } else { jbtnconnect.settext("connect"); jbtnconnect.setforeground(color.white); jbtnconnect.setbackground(color.red); } } jtferroricitire.settext(string.valueof(totalerrors)); seek { thread.sleep(300); jpanel4.repaint(1); } grab (interruptedexception ex) { logger.getlogger(mainform.class.getname()).log(level.severe, null, ex); } } grab (exception ex) { logger.getlogger(mainform.class.getname()).log(level.severe, null, ex); } } }); updateuithread.start(); }

and there other threads started above , different values updated in above thread.

my question why code not throw exception regarding ui elements updated thread? did not utilize swingutilities.invokelater(new runnable() { //code here }); , code executes perfectly...

thank you!

swing not thread safe , single threaded. should never update ui components outside event dispatching thread, equally, should never run long running processes or blocking code within edt, prevent processing new events within event queue, causing app it's hung...because has...

take @ concurrency in swing more details.

after scratching head while, realised, simple solution utilize javax.swing.timer

you want repeat update @ regular interval (300 milliseconds) , update ui, perfect, swing timer capable of scheduling updates @ regular intervals , executes phone call within context of edt!

it has ability consolidate repeated calls. means, if there "timer" action in event queue, timer not generate new one, preventing flooding edt , cause possible performance issues...

javax.swing.timer timer = new timer(300, new actionlistener() { public void actionperformed(actionevent evt) { jtfip.setenabled(!start && !autorec); jtfport.setenabled(!start && !autorec); jtfslaveid.setenabled(!start && !autorec); jtftimeout.setenabled(!start && !autorec); jtfreqinterval.setenabled(!start && !autorec); jcheckbox1.setenabled(!start && !autorec); jcbreconnect.setenabled(!start && !autorec); if (db != null) { if (!db.getisopen()) { jpbd.setbackground(color.red); jpbd.setforeground(color.white); jpbd.settext("er"); } else { jpbd.setbackground(color.green); jpbd.setforeground(color.black); jpbd.settext("ok "); } } else { jpbd.setbackground(color.red); jpbd.setforeground(color.white); jpbd.settext(" er "); } if (autorec){ jbtnconnect.settext("auto"); if (start && connected) { jbtnconnect.setforeground(color.black); jbtnconnect.setbackground(color.green); } else { jbtnconnect.setforeground(color.white); jbtnconnect.setbackground(color.red); } } else { if (start) { jbtnconnect.settext("disconnect"); jbtnconnect.setforeground(color.black); jbtnconnect.setbackground(color.green); } else { jbtnconnect.settext("connect"); jbtnconnect.setforeground(color.white); jbtnconnect.setbackground(color.red); } } jtferroricitire.settext(string.valueof(totalerrors)); } }); timer.start();

see how utilize swing timers more details

java multithreading user-interface elements invokelater

No comments:

Post a Comment