1 2 3 Previous Next 30 Replies Latest reply: Dec 28, 2010 9:34 PM by DarrylBurke RSS

    force the repaint of a JPanel

    843853
      Hi all,

      I want to create a little animation by calling an animate() function in a JPanel but repaint() doesn't force the UI refresh! I've tried to use paintImmediately() as well but it was not working better!

      Here a simplified version of my code:
      class MyPanel extends JPanel{
           
           int movX,movY;
           Image movImage;
           
           MyPanel(){          
                setSize(500, 500);      
           }
           
           void animate(int fromCell, int toCell){
           
                         movImage = Toolkit.getDefaultToolkit().getImage("image.gif")
                
                for (int i=100; i<400; i++){
                     movX = i;
                     movY = i;
                     repaint();   //--- repaint() here does not work!!!
                }
                
                movImage = null;
           }
           
           public void paintComponent(Graphics g){
                
                //--- draw background
                
                g.setColor(Color.white);
                g.fillRect( 0, 0, 500, 500);
                
                //--- draw image
      
                if (movImage!=null) g.drawImage(movImage, movX, movY, this);
           }
           
           public void update(Graphics g){
                paint(g);
           }
           
      }
      Any ideas why?
      Thanks very much for your help.
      Denis
        • 1. Re: force the repaint of a JPanel
          843853
          try this:
          Graphics g = getGraphics();
          if (g != null) paintComponent(g);
          else repaint();
          • 2. Re: force the repaint of a JPanel
            843853
            It is not recommended to call the paint method directly...

            public void repaint()

            Repaints this component.
            If this component is a lightweight component, this method causes a call to this component's paint method as soon as possible. Otherwise, this method causes a call to this component's update method as soon as possible.

            In other words, it only get painted if there is time to... try this:
            for (...)
            {
                 ...
                 repaint();
                 try
                 {
                      Thread.sleep(20); // sleep for 20 milliseconds
                 }
                 catch (Exception e)
                 {
                      e.printStackTrace();
                 }
            }
            • 3. Re: force the repaint of a JPanel
              843853
              It is not recommended to call the paint method
              directly...
              says who? active rendering is a common technique used in games. Unless you're referring to it being unsafe in swing components... I don't know much about swing. I do know swing isn't reccomended for animation-based games though...
              • 4. Re: force the repaint of a JPanel
                843853
                It is not recommended to call the paint method
                directly...
                says who? active rendering is a common technique used
                in games. Unless you're referring to it being unsafe
                in swing components... I don't know much about swing.
                I do know swing isn't reccomended for animation-based
                games though...
                I could have sworn I read it somewhere ;P
                • 5. Re: force the repaint of a JPanel
                  843853
                  I could have sworn I read it somewhere ;P
                  Here it is http://java.sun.com/products/jfc/tsc/articles/painting/index.html#swing_summary

                  Swing Painting Guidelines
                  Swing programs should understand these guidelines when writing paint code:

                  For Swing components, paint() is always invoked as a result of both system-triggered and app-triggered paint requests;update() is never invoked on Swing components.

                  Programs may trigger a future call to paint() by invoking repaint(), but shouldn't call paint() directly.

                  ...
                  • 6. Re: force the repaint of a JPanel
                    843853
                    Thanks for your replies guys but none of them worked successfully!

                    I have also tried (unsuccessfully) this one:
                    class MyPanel extends JPanel{
                       
                            int movX,movY;
                      Image movImage;
                     
                            MyPanel(){              
                                    setSize(500, 500);      
                            }
                           
                            void animate(int fromCell, int toCell){
                     
                                       movImage = Toolkit.getDefaultToolkit().getImage("image.gif")
                             
                                    for (int i=100; i<400; i++){
                                        movX = i;
                                           movY = i;
                                           repaint();   //--- repaint() here does not work!!!
                                  }
                                   
                                    movImage = null;
                            }
                           
                            public void paintComponent(Graphics g){
                             
                                    //--- draw background
                               
                                    g.setColor(Color.white);
                                    g.fillRect( 0, 0, 500, 500);
                                
                                    //--- draw image
                    
                                    if (movImage!=null) g.drawImage(movImage, movX, movY, this);
                    try{
                                   Thread.sleep(20); // sleep for 20 milliseconds
                      } catch (Exception e){
                                   e.printStackTrace();
                        }
                    
                        }
                           
                            public void update(Graphics g){
                             paint(g);
                           }
                           
                    }
                    The only interesting result so far is for the last iteration, the image.gif is displayed once with coordinates (400,400). All the other iterations are just skipped!

                    In the real code, MyPanel implements MouseListener, MouseMotionListener as well and from the mouseDragged(MouseEvent e) function I can call repaint() successfully.

                    ???
                    Denis
                    • 7. Re: force the repaint of a JPanel
                      843853
                      I've done new tests.
                      This code
                      Graphics g = getGraphics();
                      if (g != null) paintComponent(g);
                      else repaint();
                      is working fine with a jvm 1.3.1, not is not ok with a jvm 1.4.1

                      ???
                      Thanks very much for your help
                      • 8. Re: force the repaint of a JPanel
                        843853
                        Hi all,

                        I have done more tests and here the results. If I use:

                        repaint()
                        - jvm 1.3.1: no animation,
                        - jvm 1.4.2: no animation

                        repaint() + Thread.sleep(20) (or whatever value instead of 20)
                        - jvm 1.3.1: no animation,
                        - jvm 1.4.2: no animation

                        paintImmediately()
                        - jvm 1.3.1: animation (with flickering),
                        - jvm 1.4.2: sometimes I got the last image displayed!

                        paintComponent(g)
                        - jvm 1.3.1: animation (with flickering),
                        - jvm 1.4.2: sometimes I got the last image displayed!


                        Therefore I am asking myself a few questions:

                        - is repaint() definitely a bad function for animations?
                        - is jvm 1.4.2 a bad jvm for animations?
                        - or am I simply a bad developper? ;-)

                        Any help would be really appreciated.
                        Thanks
                        Denis
                        • 9. Re: force the repaint of a JPanel
                          843853
                          using swing for animation, that is brave!!

                          i will be happy if i can just get the progress bar on my form to work properly for pete's sake. swing. grrrrr

                          i finally got it to work by using paintImmediately at the end of the loop, but only if I call JFrame.show() immediately before the loop. Thank you for posting your results Denis, this was invaluable to me.

                          my code (FINALLY working) (sun JVM 1.4.1.05):

                          // initialize progress bar prbStatus
                          fraMain.show();

                          for (i = 0; ai.nextRecord(); i++) {
                               db.updateDb(ai.getRecord());
                               prbStatus.setValue(i);

                          // force JPanel to repaint
                               pnlMain.paintImmediately(0,0,
                               pnlMain.getWidth(),
                               pnlMain.getHeight());
                          }
                          • 10. Re: force the repaint of a JPanel
                            843853
                            >
                            The only interesting result so far is for the last
                            iteration, the image.gif is displayed once with
                            coordinates (400,400). All the other iterations are
                            just skipped!

                            In the real code, MyPanel implements MouseListener,
                            MouseMotionListener as well and from the
                            mouseDragged(MouseEvent e) function I can call
                            repaint() successfully.
                            The repaint runs on the EventDispatcher Thread, which also handles the mouse Events - maybe that slows down your animation..

                            also you have to call super.paintComponent(g) in the overridden paintComponent() method.
                            • 11. Re: force the repaint of a JPanel
                              843853
                              call Thread.sleep(ms) after you call repaint.
                              ...
                              
                              repaint();
                              
                              try
                              {
                                   Thread.sleep(ms);
                              }
                              catch (Exception e)
                              {
                                   e.printStackTrace();
                              }
                              
                              ...
                              • 12. Re: force the repaint of a JPanel
                                843853
                                Call

                                revalidate();

                                • 13. Re: force the repaint of a JPanel
                                  843853
                                  call Thread.sleep(ms) after you call repaint.
                                  Thread.sleep cannot provide absolute assurance that a subsequent repaint() will be successfully executed (a point that is actually implied by the inclusion of the argument "ms"in this recommendation).

                                  • 14. Re: force the repaint of a JPanel
                                    843853
                                    sorry, just noticed the attention getting "after".
                                    1 2 3 Previous Next