Java 动画期间屏幕闪烁白色

Java 动画期间屏幕闪烁白色,java,swing,flash,animation,screen,Java,Swing,Flash,Animation,Screen,我正在开发一个Java程序,我从一个简单的动画开始。它包括显示存储在阵列中的一组帧(40帧) 动画本身工作正常,但每当我运行它时,就会出现这种随机闪烁(屏幕闪烁白色)。我不知道这可能与什么有关,但我猜这与缺乏优化有关。有什么解决办法吗?下面是代码 //Handles the main interface MainUI.java package gui; import java.awt.BorderLayout; public class MainUI extends JFrame impl

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


您遇到了一些问题:

  • 永远不要直接在JFrame中绘制。JFrames有大量的功能,如果您重写它们的绘制方法,这些功能可能会受到损害。另外,由于它们没有paintComponent方法,所以不会得到默认的双缓冲——即密钥丢失
  • 而是引入一个JPanel或JComponent扩展类
  • 并使用
    paintComponent(Graphics g)
    方法而不是绘制方法绘制。这将获得默认的双缓冲,使动画看起来更平滑
  • 调用适当的超级方法。出于某种原因,您正在调用
    super.paintComponents(..)
    。对于paintComponent,这将是
    super.paintComponent(g)
    (无s)
  • 从所有绘制方法中获取程序逻辑。逻辑应该在计时器中,并且在绘制方法中只应进行绘制

  • 我自己,我不会做你正在做的任何事情,而是简单地在我的计时器内的JLabel中交换图像图标,就这样。简单干净
例如:

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

您遇到了一些问题:

  • 永远不要直接在JFrame中绘制。JFrames有大量的功能,如果您重写它们的绘制方法,这些功能可能会受到损害。另外,由于它们没有paintComponent方法,所以不会得到默认的双缓冲——即密钥丢失
  • 而是引入一个JPanel或JComponent扩展类
  • 并使用
    paintComponent(Graphics g)
    方法而不是绘制方法绘制。这将获得默认的双缓冲,使动画看起来更平滑
  • 调用适当的超级方法。出于某种原因,您正在调用
    super.paintComponents(..)
    。对于paintComponent,这将是
    super.paintComponent(g)
    (无s)
  • 从所有绘制方法中获取程序逻辑。逻辑应该在计时器中,并且在绘制方法中只应进行绘制

  • 我自己,我不会做你正在做的任何事情,而是简单地在我的计时器内的JLabel中交换图像图标,就这样。简单干净
例如:

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

同样的事情,我只是张贴与样本代码,但我迟到了。我真傻!我完全忘记了“永远不要在jframe中画画”规则。我以前做得对,但由于某种原因,我不记得这样做过。不管怎样,我实现了您建议的更改,效果很好:)+1我刚刚用示例代码发布了同样的内容,但我迟到了。我真傻!我完全忘记了“永远不要在jframe中画画”规则。我以前做得对,但由于某种原因,我不记得这样做过。不管怎样,我实现了您建议的更改,效果很好:)+1
public void actionPerformed(ActionEvent e) {
    myJLabel.setIcon(frames[currentFrame]);
    currentFame++;
    if (currentFrame >= frames.length) {
        timer.stop();
    }
}