图像在重绘时闪烁()

我找到了上一个问题的解决方案,这让我陷入了新的问题。

在下面的代码中,我使用箭头键在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) {} } 

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

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

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

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

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

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

非闪烁,工作代码。

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) { } }