Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repaint a jpanel every x seconds?

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);
}
like image 719
Alessandro Avatar asked Feb 27 '14 15:02

Alessandro


People also ask

What does JPanel repaint do?

Ideally if you want to draw in an area then you would extend JPanel with a custom paint and place it below the button. To explain repaint further - the point of 'repaint' is to tell the window manager that you have changed something that requires the component to be redrawn.

Does repaint call paintComponent?

Answer: The repaint() method of a component is called to notify the system that the component needs to be redrawn. It does not itself do any drawing (neither directly nor by calling the paintComponent() routine).

Can you draw on JPanel?

An explanation: To write or draw in a frame, we need to override the paintComponent() method in JPanel. To override means we have to inherit from JPanel.

How do I make a transparent JPanel?

You can simply create your jPanel using drag and drop, as you always do and then for changing the panel's color and making it transparent or semi-transparent you can use this code: panel. setBackground(new Color(0.0f, 0.0f, 0.0f, 0.5f));


1 Answers

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
    }

}
like image 111
Masudul Avatar answered Sep 22 '22 18:09

Masudul