This discussion is archived
1 2 3 Previous Next 30 Replies Latest reply: Dec 28, 2010 7:34 PM by DarrylBurke Go to original post RSS
  • 15. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
     
  • 16. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Nice. You're my hero. That one works, nothing else I found worked. Awesome. Props. You have my gratitude. A+. I'd offer you a job, but I don't own a company.
  • 17. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Er....

    It didn't quote. I was replying to:
    Call

    revalidate();
  • 18. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    I was having a similar problem with a JPanel where I needed to dynamically add or take away labels. The only way I could get it to repaint was to resize the window or do some action which caused a JScrollPane in another panel to turn on or off by adding and removing text.

    I tried every suggestion mentioned here, revalidate() did the trick.

    Thanks.
  • 19. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Hello,

    i'm facing quite the same problem
         public void HighlightCell(boolean highlight)
         {
              m_highlight=highlight;
              //this.updateUI();
              Graphics g = getGraphics();
              if (g != null) paintComponent(g);
              else repaint();
              update(getGraphics());
              revalidate();
         }
         public void paintComponent(Graphics grp)
         {
              super.paintComponent(grp);
              Graphics2D g2d = (Graphics2D) grp;
              // draw the image using the AffineTransform
              if (m_highlight)
                   g2d.setXORMode(Color.BLUE);
              else
                   g2d.setPaintMode();
                   
              g2d.drawImage(m_img, m_transformer, this);     
         }
    HighlightCell is called from an actionButton click. From there i would like to repaint the cell in XORMode. But calling repaint() does not do the trick neither update revalidate or whatever...
    But if i click on maximise or iconify the chage operates...
    What should i do ? Thanks for your help.
  • 20. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    so start your own thread
  • 21. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Literally - the solution is to instantiate a new Thread, put the processing that you need to do in the run method, and set it running when you would have otherwise started the processing that you need to do. This is the best solution I have found. This frees up the GUI to resume the repaint in the background while your processing continues.
  • 22. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    I had the same problem, and found an example of how to fix it (by putting the animation code in another string) at http://www.developer.com/java/other/article.php/158709, by a professor named Dick Baldwin (His tutorials can be found at http://dickbaldwin.com/, and are great resources)

    I took a class from Prof. Baldwin, but I have no commercial association with him nor commercial interest in his tutorials (So I hope that this posting does not violate the code of conduct)
  • 23. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    this has solved same problem on my project too!
    thanx bxpeng.
  • 24. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    This problem actually, from my experience, calls for using 2 Threads that will switch strictly.
    In the first thread, you call a repaint every time you have data ready for displaing. In the other thread, you do any computations necessary. Also, you do the sleeping in this thread.
    I think that you can learn best from an example, so I give you some animation code that should work 100% (I tested it before posting).
    //contents of JavaDraw.java:
    
    package javadraw;
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Toolkit;
    import javax.swing.JWindow;
    
    public class AnimationWindow extends JWindow{
    
        // this variable is used for strict switching between the threads
        public static boolean computing = false;
        // this is how fast the animation will be (one change every 10 ms)
        public static int delay = 10;
        // gray is iterated every computation cycle
        static int gray = 0;
        
        public static void main(String[] args) {
            //some initialization stuff
            AnimationWindow w = new AnimationWindow();
            w.setSize(100,100);
            centerOnScreen(w);
            w.setVisible(true);
            
            // the threads switch strictly - first the ComputeThread, then AnimationWindow
            // and again the ComputeThread ...
            new ComputeThread(w);
            while(true){
                w.draw();
            }
        }
    
        // just to have the animation in the center of the screen;
        // this method is not necessary for the correct functionality of the animation
        private static void centerOnScreen(JWindow w) {
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            w.setLocation((int)(screenSize.getWidth()-w.getWidth())/2,
                    (int)(screenSize.getHeight()-w.getHeight())/2);
        }
        
        // This method belongs to the AnimationWindow object. 
        // It is synchronized - i.e. no other user thread can call a method on the same 
        // object while this method is being executed.
        // It must be synchronized in order for the Thread switching to work correctly.
        synchronized public void compute(){
            while(!AnimationWindow.computing){
                        try {
                            wait();
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
            try {
                // HERE you set the first thread to sleep, while the other one can draw freely.
                // Note that if you set the delay to something close to (or) zero, the animation
                // won't be smooth anymore, because JVM won't have enough time for a redraw.
                Thread.sleep(AnimationWindow.delay);
                } catch (InterruptedException ex) {
                ex.printStackTrace();
                }
            
            //compute something... (this part is, of course, not necessary)
            for(int i = 0; i<10000;i++){
                for(int j = 0;j<10000;j++) ; //some CPU-intensive computation
            }
            
            //set the next color to draw
            if(gray+1 >= 256) System.exit(0);
            gray++;
            
            AnimationWindow.computing = false;
            notifyAll();
        }
        
        // method whose only purpose is to call repaint() every time new data is computed
        synchronized public void draw(){
            while(AnimationWindow.computing){
                       try {
                            wait();
                        } catch (InterruptedException ex) {
                        ex.printStackTrace();
                        }    
                    }
            repaint();
            AnimationWindow.computing = true;
            notifyAll(); 
        }
        
        // the paint method that is scheduled for calling after you call a repaint();
        @Override
        public void paint(Graphics g){
            g.setColor(new Color(gray,gray,gray));
            g.fillRect(0,0,100,100);
        }
    
    }
    
    // The thread that calls any CPU-intensive computations
    // It also prepares data for drawing.
    class ComputeThread extends Thread{
        AnimationWindow syncObject;
        public ComputeThread(AnimationWindow w){
            syncObject = w;
            start(); //start() dispatches the ComputeThread and calls its run() method.
        }
        
        @Override
        public void run(){
            while(true){
                syncObject.compute();
            }
        }
    }
  • 25. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Your approach to animation is slightly flawed.
    What I advise is a game loop or some sort of program timer that schedules repaints every so many ms.

    1) Create a timer object and use the method scheduleAtFixedRate.
    2) Create a thread that calls an animation update and the repaint (same as #1 but explicit)

    Good luck! :)
  • 26. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Use something like component.paintImmediately(0, 0, component.getWidth(), component.getHeight())

    Maybe the JVM has changed since the earlier posts, but repaint() does NOT cause the component to be repainted as soon as possible, contrary to the JavaDoc. It may actually allow a time delay to wait for similar events, in order to improve overall efficiency.

    For example, if you have a regular event with a repaint() every 500 or 100 ms, the RepaintManager (?) may repaint each time at first, but then it adapts to this regular pattern and waits for all the calls to finish before painting anything. The source of this information is actual experimentation.

    See also the Note under "Paint Processing" at http://java.sun.com/products/jfc/tsc/articles/painting/
  • 27. Re: force the repaint of a JPanel
    843853 Newbie
    Currently Being Moderated
    Actually, you have at least a couple problems that I can see in just a quick glance.

    1 - paintComponent (is used in SWING)
    2 - loading with Toolkit has never been advocated by anyone for anything other than tiny images. If you're image is bigger than a thumbnail, then you're not getting it loaded. Use ImageIO to load it.

    I have literally, have 1000's of object running full screen in SWNG using repaint() and not have a problem with the graphics refreshing, and lest you think it was on a mega box, it was on anything from a 1.8GHz laptop to a dual quadcore. If you do it right, it will work right.
  • 28. Re: force the repaint of a JPanel
    morgalr Explorer
    Currently Being Moderated
    If you absolutely have to have paints done exactly when you decide, then get rid of your passive approach and use active rendering.
  • 29. Re: force the repaint of a JPanel
    gimbal2 Guru
    Currently Being Moderated
    edit: nvm, this thread is too old.