【问题标题】:Screen flashing white during animation动画期间屏幕闪烁白色
【发布时间】:2014-08-02 03:13:06
【问题描述】:

我正在开发一个 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();
                }
            }
        });
    }
}

【问题讨论】:

    标签: java swing flash animation screen


    【解决方案1】:

    你遇到了一些问题:

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

    • 我自己,我不会做任何你正在做的事情,而是会简单地在我的 Timer 内的 JLabel 中交换 ImageIcons,仅此而已。简单干净。

    例如:

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

    【讨论】:

    • 与我刚刚发布的示例代码相同,但我迟到了。
    • 我真傻!我完全忘记了“永远不要在 jframe 中绘图”规则。我以前做过正确的,但由于某种原因我不记得了。无论如何,我实施了您建议的更改,并且运行良好:) +1
    猜你喜欢
    • 2015-03-24
    • 1970-01-01
    • 2014-10-14
    • 2010-11-20
    • 1970-01-01
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多