JFrame重绘图像闪烁

JFrame repainting image blinking

我在使用命令 super.paintComponents(g) 时遇到问题;更新 JFrame 时。我遇到的问题是我正在加载的图像在代码为 运行 时闪烁。我很确定代码是双缓冲的,并且没有在网上找到任何有用的资源来解决这个问题。这是我的第一个问题,所以请容忍任何格式错误。

这是我的全部代码(下面的片段):

public class GAME extends JFrame implements KeyListener, MouseMotionListener {
int mouseX, mouseY;

public static ArrayList<Images> images = new ArrayList<Images>();
public static String lastKeyPressed = null;

public GAME() {
    this.addMouseMotionListener(this);
    this.addKeyListener(this);
}

public void mouseDragged(MouseEvent e) {
    mouseX = e.getX();
    mouseY = e.getY();
}

public void mouseMoved(MouseEvent e) {
    mouseX = e.getX();
    mouseY = e.getY();
}

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == e.VK_LEFT) {
        lastKeyPressed = "LEFT";
    } else if (e.getKeyCode() == e.VK_RIGHT) {
        lastKeyPressed = "RIGHT";
    } else if (e.getKeyCode() == e.VK_UP) {
        lastKeyPressed = "UP";
    } else if (e.getKeyCode() == e.VK_DOWN) {
        lastKeyPressed = "DOWN";
    }
}

public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

}

@Override
public void paint(Graphics g) {
    super.paintComponents(g);
    for (int i = 0; i < images.size(); i++) {
        g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
    }
}

public static void main(String[] args) throws IOException, InterruptedException {
    GAME frame = new GAME();
    Dimension dim = new Dimension(800, 600);
    frame.setPreferredSize(dim);
    frame.setSize(dim);
    frame.setResizable(false);
    frame.setTitle("GAME");
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    Images test = new Images("unnamed.png");
    images.add(test);
    while (true) {
        if (lastKeyPressed == "LEFT") {
            test.xpos -= 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "RIGHT") {
            test.xpos += 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "UP") {
            test.ypos -= 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "DOWN") {
            test.ypos += 5;
            lastKeyPressed = null;
        }
        frame.repaint();
        Thread.sleep(100);
    }
}

}

这是图片 class:

public class Images {

String name;
BufferedImage img;
int xpos;
int ypos;

public Images (String Name) throws IOException{
    name = Name;
    xpos = 40;
    ypos = 90;
    System.out.println(name);
    System.out.println("PATH: " + GAME.class.getResource(name));
    URL file = getClass().getClassLoader().getResource(name);
    img = ImageIO.read(file);
}
}

您可能只想看到以下内容:

我的绘画方法:

@Override
public void paint(Graphics g) {
    super.paintComponents(g);
    for (int i = 0; i < images.size(); i++) {
        g.drawImage(images.get(i).img, images.get(i).xpos, images.get(i).ypos, null);
    }
}

主要 class 中的代码块,即 运行 游戏:

Images test = new Images("unnamed.png");
    images.add(test);
    while (true) {
        if (lastKeyPressed == "LEFT") {
            test.xpos -= 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "RIGHT") {
            test.xpos += 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "UP") {
            test.ypos -= 5;
            lastKeyPressed = null;
        } else if (lastKeyPressed == "DOWN") {
            test.ypos += 5;
            lastKeyPressed = null;
        }
        frame.repaint();
        Thread.sleep(100);
    }

(我添加了 Thread.sleep 因为它似乎降低了闪烁发生的速度)

这是正在发生的事情的 gif(我只是使用了 'test' 的第一个 Google 结果作为图像): http://i.imgur.com/WjLCSvu.gif?1

感谢任何帮助和改进我的代码的一般建议。谢谢。

不要覆盖 paint 顶级容器,例如 JFrame 没有双缓冲,而是使用 JPanel 并覆盖其 paintComponent 方法。 JPanel 默认为双缓冲。

然后,将面板添加到您想要的任何容器中

在进行任何自定义绘画之前,请不要忘记调用它的 super 方法 (super.paintComponent)。

仔细查看 Painting in AWT and Swing and Performing Custom Painting,了解有关 Swing 绘画工作原理的更多详细信息

这只是您不应该(从 JFrame 扩展并)覆盖顶级容器的 paint 的原因之一,请查看

  • How can I set in the midst?
  • Graphics rendering in title bar
  • Java JFrame .setSize(x, y) not working?
  • How to get the EXACT middle of a screen, even when re-sized

还有一些