在动画期间屏幕闪烁白色

时间:2014-06-11 22:14:04

标签: java swing flash animation 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();
    }
}

/ ----

//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;
    }
}

/ ----

//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();
                }
            }
        });
    }
}

1 个答案:

答案 0 :(得分: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();
    }
}