Search code examples
javaswingjpanelpaintcomponent

Why is my while loop not working in paintComponent?


When I run this code, I see nothing but a blank(white) Panel and I would like to know why.

Here is my code:

Graph.java

public class Graph extends JPanel {
    private static final long serialVersionUID = -397959590385297067L;
    int screen=-1;
    int x=10;
    int y=10;
    int dx=1;
    int dy=1;       
    boolean shouldrun=true;
    imageStream imget=new imageStream();

        protected void Loader(Graphics g){

            g.setColor(Color.black);
            g.fillRect(0,0,x,y);
            x=x+1;
            y=y+2;

        }


        @Override
        protected void paintComponent(Graphics g){
            super.paintComponent(g);
                while(shouldrun){
                    Loader(g);   
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }    
                }   
        }
}

Solution

  • Do not ever call Thread.sleep() on the Event Dispatch Thread!!!

    This causes the thread that actually redraws the screen and makes controls responsive to stop doing anything.

    For animations, use a Timer. Don't worry about writing the while loop yourself, just tell the Timer to fire every so often, and change the values of x and y inside that timer. Something like:

    // this is an **inner** class of Graph
    public class TimerActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            x += dx;
            y += dy;
        }
    }
    
    // snip
    
    private final Timer yourTimer;
    
    public Graph() {
        yourTimer = new Timer(2000, new TimerActionListener());
        timer.start();
    }
    
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(Color.black);
        g.fillRect(0,0,x,y);
    }