Java 重复重新绘制缓冲区图像时防止水平线/半帧

Java 重复重新绘制缓冲区图像时防止水平线/半帧,java,swing,animation,repaint,flicker,Java,Swing,Animation,Repaint,Flicker,我有一个显示动画的swing组件。动画帧在BuffereImage中动态计算,并以大约30fps的速度显示 问题是,它时不时地会产生半帧的输出——在下面给出的测试用例中,输出中会出现非常明显的不连续性,而这种不连续性应该是黑白闪烁的 谁能告诉我是什么原因导致了这个小故障,以及如何修复它 请注意,运行此代码将产生快速闪烁的灯光 我没有注意到任何明显的间断,但我不想再盯着它看太久。我在Windows 7上运行JDK7。试试或者。这可能是硬件/操作系统问题。我在另一台机器上尝试过这个问题-看起来像是硬

我有一个显示动画的swing组件。动画帧在BuffereImage中动态计算,并以大约30fps的速度显示

问题是,它时不时地会产生半帧的输出——在下面给出的测试用例中,输出中会出现非常明显的不连续性,而这种不连续性应该是黑白闪烁的

谁能告诉我是什么原因导致了这个小故障,以及如何修复它

请注意,运行此代码将产生快速闪烁的灯光


我没有注意到任何明显的间断,但我不想再盯着它看太久。我在Windows 7上运行JDK7。试试或者。这可能是硬件/操作系统问题。我在另一台机器上尝试过这个问题-看起来像是硬件/操作系统问题@camickr我明白你所说的盯着它看的意思了——它会更加强烈地寻找那些不存在的东西——它们在我的xp设备上可以直接看到!
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;

class Animation extends JComponent {
    FrameSource framesource;
    public Animation(FrameSource fs)
    {
        this.framesource = fs;
        setDoubleBuffered(true); 
        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    framesource.computeNextFrame();
                    Animation.this.repaint();
                    try {Thread.sleep(30);} catch (InterruptedException e) {}
                }
            }
        }).start();
    }
    public Dimension getPreferredSize() {return new Dimension(500,500);}
    public void paintComponent(Graphics g) {
            g.drawImage(framesource.getCurrentFrame(), 0,0,null);
    }
}
class FrameSource
{
    private BufferedImage currentframe;
    public BufferedImage getCurrentFrame() {return currentframe;}
    int frameCount = 0;
    public void computeNextFrame()
    {
        BufferedImage nextFrame = new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);
        for (int x=0;x<500;x++)
            for (int y=0;y<500;y++)
            {
                nextFrame.setRGB(x, y, (frameCount%2==0)?16777215:0);
            }
        frameCount++;
        currentframe = nextFrame;
    }
}
public class Flickertest {
        public static void main(String[] args) 
        {
            JFrame frame = new JFrame();
            FrameSource fs = new FrameSource();
            Animation a = new Animation(fs);
            frame.getContentPane().add(a);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
}