Java 动画期间屏幕闪烁白色
我正在开发一个Java程序,我从一个简单的动画开始。它包括显示存储在阵列中的一组帧(40帧) 动画本身工作正常,但每当我运行它时,就会出现这种随机闪烁(屏幕闪烁白色)。我不知道这可能与什么有关,但我猜这与缺乏优化有关。有什么解决办法吗?下面是代码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
//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)
- 调用适当的超级方法。出于某种原因,您正在调用
。对于paintComponent,这将是super.paintComponents(..)
(无s)super.paintComponent(g)
- 从所有绘制方法中获取程序逻辑。逻辑应该在计时器中,并且在绘制方法中只应进行绘制
- 我自己,我不会做你正在做的任何事情,而是简单地在我的计时器内的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)
- 调用适当的超级方法。出于某种原因,您正在调用
。对于paintComponent,这将是super.paintComponents(..)
(无s)super.paintComponent(g)
- 从所有绘制方法中获取程序逻辑。逻辑应该在计时器中,并且在绘制方法中只应进行绘制
- 我自己,我不会做你正在做的任何事情,而是简单地在我的计时器内的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();
}
}