How to repaint a jpanel every x seconds?

13,404

Use Swing Timer,

class GamePanel extends JPanel implements ActionListener{

 Timer timer=new Timer(1000, this);

 public GamePanel() {
   timer.start();// Start the timer here.
 }

 public void actionPerformed(ActionEvent ev){
    if(ev.getSource()==timer){
      repaint();// this will call at every 1 second
    }

}
Share:
13,404
Alessandro
Author by

Alessandro

Updated on June 09, 2022

Comments

  • Alessandro
    Alessandro almost 2 years

    i would like to know how to repaint and update the background of a JPanel every x seconds...This is my code:

    package view;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class GamePanel extends JPanel {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final JLabel score;
    private final static String[] BACKGROUND_COLORS = {"black", "blue", "darkpurple", "purple"};
    private int i = 0;
    
    public GamePanel() {
        this.score = new JLabel("Score: ");
        this.score.setBounds(0, 0, 40, 20);
        this.score.setOpaque(false);
        this.score.setForeground(Color.GREEN);
        this.add(score);
    }
    
    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        //Image background = new ImageIcon(this.getClass().getResource("/images/" + BACKGROUND_COLORS[i] + "Background.png")).getImage();
        //g.drawImage(background, 0, 0, null);
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Image background = new ImageIcon(this.getClass().getResource("/images/" + BACKGROUND_COLORS[i] + "Background.png")).getImage();
                g.drawImage(background, 0, 0, null);
                revalidate();
                repaint();
                System.out.println("trying my timer");
                i++;
                if (i == 4) {
                    i = 0;
                }
            }
        });
        timer.start();
    }
    }
    

    I have 2 issues with this code: 1- The JPanel doesn't get painted at all. 2- The first print is ok, then the the number of prints is doubled each time. Any suggestion? Thank you in advance

    UPDATE: I solved the problem in this way:

    package view;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class GamePanel extends JPanel {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final JLabel score;
    private int i = 0;
    private final static String[] BACKGROUND_COLORS = {"black", "blue", "darkpurple", "purple"};
    private final static int DELAY = 10000;
    
    public GamePanel() {
        this.score = new JLabel("Score: ");
        this.score.setBounds(0, 0, 40, 20);
        this.score.setOpaque(false);
        this.score.setForeground(Color.GREEN);
        this.add(score);
        Timer timer = new Timer(DELAY, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                i++;
                if (i == 4) {
                    i = 0;
                }
            }
        });
        timer.start();
    }
    
    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        Image background = new ImageIcon(this.getClass().getResource("/images/" + BACKGROUND_COLORS[this.i] + "Background.png")).getImage();
        g.drawImage(background, 0, 0, null);
        revalidate();
        repaint();
    }
    

    UPDATE 2:

    package view;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class GamePanel extends JPanel {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final JLabel score;
    private int currentImage;
    private final List<Image> backgrounds = new ArrayList<>();
    private static final String[] BACKGROUND_COLORS = {"black", "blue", "darkpurple", "purple"};
    private static final int DELAY = 1000;
    
    public GamePanel() {
        super();
        this.score = new JLabel("Score: ");
        this.score.setBounds(0, 0, 40, 20);
        this.score.setOpaque(false);
        this.score.setForeground(Color.GREEN);
        this.add(score);
        for (final String s : BACKGROUND_COLORS) {
            backgrounds.add(new ImageIcon(this.getClass().getResource("/images/" + s + "Background.png")).getImage());
        }
        final Timer timer = new Timer(DELAY, new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                repaint();
                currentImage++;
                if (currentImage == BACKGROUND_COLORS.length) {
                    currentImage = 0;
                }
            }
        });
        timer.start();
    }
    
    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        g.drawImage(backgrounds.get(this.currentImage), 0, 0, null);
    }