在动画期间屏幕闪烁白色

GRo*_*tar 1 java flash animation swing screen

我正在开发一个Java程序,我开始使用一个简单的动画.它包括显示存储在一个数组(40帧)中的一组帧.

动画本身正在正常工作,虽然每当我运行它时,我会得到随机闪烁(屏幕闪烁白色).我不知道它可能与什么有关,但我猜它与缺乏优化有关.有解决方案吗 这是下面的代码

//Handles the main interface
MainUI.java

package gui;

import java.awt.BorderLayout;

public class MainUI extends JFrame implements ActionListener{

    //main panel
    private JPanel contentPane;

    //animation
    private ImageIcon[] frames; //animation frames
    private Timer timer; 
    private int delay = 50; //0,5s
    private int currentFrame = 0;

    public MainUI() {

        Map M = new Map();

        loadAnimation(M);

        //Main frame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 640, 360);
        setResizable(false);
        setTitle("Monopoly Java");

        //Panel
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JLabel label = new JLabel("");
        //label.setIcon(frames[0]);
        contentPane.add(label, BorderLayout.CENTER);
    }

    public void loadAnimation(Map M) {

        timer = new Timer(delay, this);
        timer.start();

        frames = M.getFrames();
    }

    public void paint(Graphics g) {

        super.paintComponents(g);

        frames[currentFrame].paintIcon(this, g, 0, 0);

        if (currentFrame == frames.length - 1) timer.stop();
        else currentFrame++;
    }

    public void actionPerformed(ActionEvent e) {
        repaint();
    }
}
Run Code Online (Sandbox Code Playgroud)

/ ----

//Class responsible for loading the images
Map.java

package gui;

import javax.swing.ImageIcon;

public class Map {

    //animation frames array
    private ImageIcon[] frames;

    public Map() {  

        loadAnimationFrames();
    }

    public void loadAnimationFrames() {

        //Loading animation frames
        frames = new ImageIcon[40];

        for (int i = 0; i < 40; i++) {

            String frameName = "f" + (i + 1);
            frames[i] = new ImageIcon("src/gui/Images/Frames/" + frameName + ".jpg");
        }
    }

    public ImageIcon[] getFrames() {
        return frames;
    }
}
Run Code Online (Sandbox Code Playgroud)

/ ----

//class which contains main
main.java

package gui;

import java.awt.EventQueue;

public class main {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainUI frame = new MainUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 6

你有一些问题:

  • 永远不要直接在JFrame中绘制.JFrame具有大量功能,如果覆盖其绘制方法,可能会受到影响.此外,由于它们没有paintComponent方法,因此您不会获得默认的双缓冲 - 这是一个关键的损失.
  • 而是在JPanel或JComponent扩展类中绘制.
  • 并且在paintComponent(Graphics g)方法中绘制而不是绘制方法.这将使您获得默认的双缓冲,这将使您的动画看起来更流畅.
  • 调用适当的超级方法.你是super.paintComponents(....)出于某种原因打电话的.对于paintComponent,那将是super.paintComponent(g)(没有s)
  • 所有绘画方法中获取程序逻辑.逻辑应该在计时器中,并且只应在绘画方法中进行绘画.

  • 我自己,我不会做任何你正在做的事情,而是简单地将ImageIcons交换到我的Timer里面的JLabel,就是这样.简单干净.

例如:

public void actionPerformed(ActionEvent e) {
    myJLabel.setIcon(frames[currentFrame]);
    currentFame++;
    if (currentFrame >= frames.length) {
        timer.stop();
    }
}
Run Code Online (Sandbox Code Playgroud)