java - Display an image using EventDispatchThread vs without -


so i'm trying display image(ball) i'll control user input. know, image gets displayed on intervals using thread's sleep method.

i've made 2 classes, 1 extends jpanel , other extends jframe. jpanel subclass looks this:

 public class ballpanel extends jpanel {     private image ball;     private int x,y;     public ballpanel(){         try {             ball=imageio.read(new file("c:\\users\\owner\\desktop\\ball.png"));         } catch (ioexception e) {             // todo auto-generated catch block             e.printstacktrace();         }         x=10;         y=10;         thread thread = new thread() {             @override             public void run(){                     loop();         }       };         thread.start();     }     public void paintcomponent(graphics g){         super.paintcomponent(g);         g.drawimage(ball,x,y,null);     }     public void loop(){         while(true){             repaint();             try {                 thread.sleep(10);             } catch (interruptedexception e) {                 // todo auto-generated catch block                 e.printstacktrace();             }         }     } } 

in loop method call sleep method allow repaint called on intervals. then, loop() called in constructor.

the jframe subclass looks this:

    public class ballframe extends jframe {      public ballframe(){         setvisible(true);         setsize(800,800);         setdefaultcloseoperation(exit_on_close);         setcontentpane(new ballpanel());     }     public static void main(string args[]){         //swingutilities.invokelater(new runnable() {              //   @override               //  public void run() {                     new ballframe();                // }     //});  } } 

now interesting, or perhaps confusing thing, when run code shown here, anonymous inner class commented out, ball doesn't appear. need re-size frame (i.e call repaint) before ball shown. however, when call through dispatch thread using anonymous inner class ball appears every time run code. reason this?

it has little starting ui within edt or not (although should cause can cause lots of other weird , interesting issues) , more fact you've called setvisible before you've established contents of ui.

this possibly example of race condition between system trying edt , running , os calls responding before it's established.

in either case should start ui within edt , call setvisible last.

swing can lazy updating ui, deliberate design choice idea. don't want ui updated after each , every change make (like adding/removing components), hands on of control developer decided when it's best revalidate container hierarchy , request repaints

i avoid using thread update state of ui cause dirty paints swing uses passive rendering approach (painting when feels it's required) , consider using swing timer updated within edt or use bufferstrategy , employ active rendering approach, can control


Comments