Wie repaint ein jpanel alle x Sekunden?

ich würde gerne wissen, wie man repaint und update dem hintergrund eines JPanel alle x Sekunden...Das ist mein 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();
}
}

Ich habe 2 Probleme mit diesem code:
1 - Das JPanel nicht lackiert werden überhaupt.
2 - Der erste Druck ok ist, dann die Anzahl der Ausdrucke wird verdoppelt für jedes mal.
Jede Anregung? Vielen Dank im Voraus

UPDATE: ich habe das problem gelöst, in dieser Weise:

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);
}
  • Nehmen, dass Timer aus der paintComponent(Graphics) Methode.
  • Zeigen Sie uns Ihre main Methode.
  • Vielen Dank Josh, das hat geklappt.
  • I solved the problem in this way: - Nein, das ist falsch! Verwenden Sie niemals revalidate() oder repaint() in einem Malerei-Methode. Die repaint() wird eine unendliche Schleife verursachen.
  • Auch sollte man nicht Lesen die Bilder in der Malerei-Methode. Erstellen Sie ein array/Liste der Bilder, die beim erstellen der Klasse. Die Malerei Methode sollte nur malen das passende Bild.
  • Ich brauche repaint() um sicherzustellen, dass die änderung angewendet wird, in den hintergrund. Haben Sie Jungs wissen, einige bessere Möglichkeiten?
  • soll ich anrufen, die repaint() innerhalb der ActionPerformed Methode?
  • should i call the repaint() inside the ActionPerformed method? - das ist das, was Masud vorgeschlagen, und Sie akzeptiert diese Antwort, also, warum haben Sie nicht umgesetzt, das als Antwort gegeben?
  • du bist gooddamn Recht Jungs, ich entschuldige mich, ich habe aktualisiert mein Lösung bei UPDATE 2 von meinem ersten post
  • Danke. Umgekehrt Stimmen von -1 bis +1.

Schreibe einen Kommentar