重绘时图像闪烁()

时间:2012-06-03 10:27:02

标签: java image swing custom-controls flicker

我找到了previous question的解决方案,这让我陷入了新的问题。

在下面的代码中,我使用箭头键在JFrame周围移动图像。但每次按箭头键时,图像看起来都会闪烁,这在连续按下按键时非常明显。

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class TestProgram extends JFrame implements KeyListener {
    private BufferedImage TestImage;
    private int cordX = 100;
    private int cordY = 100;

    public TestProgram() {
        setTitle("Testing....");
        setSize(500, 500);
        imageLoader();
        setVisible(true);
    }

    public void imageLoader() {
        try {
            String testPath = "test.png";
            TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));

        } catch (IOException ex) {
            ex.printStackTrace();
        }

        addKeyListener(this);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(TestImage, cordX, cordY, this);
    }

    public static void main(String[] args) {
        new TestProgram();
    }


    public void keyPressed(KeyEvent ke) {
        switch (ke.getKeyCode()) {
            case KeyEvent.VK_RIGHT: {
                cordX+=5;
            }
            break;
            case KeyEvent.VK_LEFT: {
                cordX-=5;
            }
            break;
            case KeyEvent.VK_DOWN: {
                cordY+=5;
            }
            break;
            case KeyEvent.VK_UP: {
                cordY-=3;
            }
            break;
        }
        repaint();
    }

    public void keyTyped(KeyEvent ke) {}

    public void keyReleased(KeyEvent ke) {}
}

有没有解决方法可以避免这种情况?

编辑:上面是完整的工作代码。我发现很难在其中加入双缓冲器。那个人可以帮助我吗?

2 个答案:

答案 0 :(得分:6)

非闪烁,正常工作的代码。

Repaint()不只是调用paint()方法。 repaint()方法实际上调用update()方法,然后默认的update()方法调用paint()方法。所以只需覆盖update()方法。如上所述正确绘制为BufferedImage。

现在应该可以了。它在这里工作得很好。我只使用了不同的图像路径。

import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class TestProgram extends JFrame implements KeyListener {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Image TestImage;
    private BufferedImage bf;
    private int cordX = 100;
    private int cordY = 100;

    public TestProgram() {
        setTitle("Testing....");
        setSize(500, 500);
        imageLoader();
        setVisible(true);
    }



    public void imageLoader() {
        try {
            String testPath = "test.png";
            TestImage = ImageIO.read(getClass().getResourceAsStream(testPath));

        } catch (IOException ex) {
            ex.printStackTrace();
        }

        addKeyListener(this);
    }

    public void update(Graphics g){
           paint(g);
    }

    public void paint(Graphics g){

        bf = new BufferedImage( this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);

    try{
    animation(bf.getGraphics());
    g.drawImage(bf,0,0,null);
    }catch(Exception ex){

    }
}

    public void animation(Graphics g) {
        super.paint(g);
        g.drawImage(TestImage, cordX, cordY, this);
    }

    public static void main(String[] args) {
        new TestProgram();
    }

    public void keyPressed(KeyEvent ke) {
        switch (ke.getKeyCode()) {
        case KeyEvent.VK_RIGHT: {
            cordX += 5;
        }
            break;
        case KeyEvent.VK_LEFT: {
            cordX -= 5;
        }
            break;
        case KeyEvent.VK_DOWN: {
            cordY += 5;
        }
            break;
        case KeyEvent.VK_UP: {
            cordY -= 3;
        }
            break;
        }
        repaint();
    }

    public void keyTyped(KeyEvent ke) {
    }

    public void keyReleased(KeyEvent ke) {
    }
}

答案 1 :(得分:4)

你必须使用缓冲区来摆脱闪烁。 对于图像,有BufferedImage Buffer:

BufferedImage bf = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);

然后将图像绘制到屏幕上,如下所示:

g.drawImage(bf, 0, 0, null);