Search code examples
javaswingpaintgraphics2d

Dynamically repaint Panel


I'm trying to do a program that shows an animation of how a cistern fills with time. The problema is that I can't get it to refresh everytime... Here's the code: It Works but it doesn't refresh in the loop, but if I manually resize the window I can see it's new paint in the Panel:

static class _cistern extends JPanel{

    private volatile double _maxCapacity;
    private double _flux;
    private volatile double currentStorage = 0.0;
    private boolean IsStarted = false;
    private volatile int Up = 1;

    private Thread Fill = new Thread(new Runnable(){
         @Override
        public void run(){
            while(currentStorage < _maxCapacity){
                currentStorage += _flux;
                try{Thread.sleep(500);}catch(Exception ex){}
                repaint();
            }
        }
    });

    public _cistern(double MaximunCapacity, double Flux, double CurrentStorage){
        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.BLACK);
        IsStarted = true;
        Fill.start();
    }

     @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.drawOval(getWidth()/20, getHeight()/15, getWidth() - getWidth()/10, getHeight() - getHeight()+20);
        g2.drawLine(getWidth()/20, getHeight()/15+10, getWidth()/20, (getHeight() - getHeight()/15)-10);
        g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20), getWidth() - getWidth()/10, getHeight() - getHeight()+20);
        g2.drawLine(getWidth() - getWidth()/20, getHeight()/15 +10, getWidth() - getWidth()/20, (getHeight() - getHeight()/15)-10);

        if(IsStarted){ //I know I have some drawings wrong here
                       //I can fix them but I just want this to refresh dinamically. The problema is the REFRESH PAINT.
                       //If you test code and see bad drawing, that's not the problema, I want to see it refreshing :P, that's the question. Don't fix this
            g2.setColor(Color.BLUE);
            g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20) - Up++, getWidth() - getWidth()/10, getHeight() - getHeight()+20 - Up++);

            g2.drawLine(getWidth()/20, (getHeight() - getHeight()/15)-10, getWidth()/20, (getHeight() - getHeight()/15)-10);
            g2.drawLine(getWidth() - getWidth()/20, getHeight()/15 +10, getWidth() - getWidth()/20, (getHeight() - getHeight()/15)-10);

            g2.drawOval(getWidth()/20, (getHeight() - getHeight()/15 - 20), getWidth() - getWidth()/10, getHeight() - getHeight()+20);
        }

    }

}

Thanks :P


Solution

  • After some time of looking at my code I remembered I was using a Thread to call and EDT... So I just had to add this:

    private Thread Fill = new Thread(new Runnable(){
             @Override
            public void run(){
                while(currentStorage < _maxCapacity){
                    currentStorage += _flux;
                    try{Thread.sleep(500);}catch(Exception ex){}
                    SwingUtilities.invokeLater(new Runnable(){
                    public void run(){
                    revalidate();
                    repaint();
                    }
                    });
                }
            }
        });