双缓冲JFrame [英] Double Buffer a JFrame

查看:148
本文介绍了双缓冲JFrame的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读很多关于Double Buffering的内容,因为我正在开发2D游戏。我遇到了许多不同的实现策略,但我不确定Double Buffering如何适合我创建游戏窗口的方式。例如,我遇到的一篇文章(http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering)建议使用单独的绘图方法;但是,我怀疑如果您正在绘制形状,而不是向窗口添加组件,这将适用。

I have been reading a lot about Double Buffering as I am working on a 2D game. I have come across many different strategies for implementation, but am unsure how Double Buffering would fit into the way I have created my game window. For example, one article I came across (http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering) suggested having a separate method for drawing; however, I suspect this would be applicable if you were drawing shapes, instead of adding components to the window.

这是我的主要GUI代码(省略了keylistener方法)

Here is my main GUI code (keylistener methods omitted)

public class MainWindow extends JFrame implements KeyListener{
private Dimension dim;
private CardLayout layout;
private JPanel panel;
private JLayeredPane gameLayers;
private Menu menu;
private MiniGame miniGame;
private Board board;
private Sprite sprite;
private Game game;
private Map map;
private GameState gs;

private Boolean[] keys;


public MainWindow(Game game, GameState gs, Map map, Sprite sprite){
    //Call superclass.
    super();

    addKeyListener(this);

    //Sore references to critical game components.
    this.game = game;//So we can call methods when an event occurs.
    this.gs = gs;
    this.map = map;//Used to construct the board.
                    //The board needs to know the layout of the map.
    this.sprite = sprite;//Used to add the sprite to one of the layers.

    //Instantiate objects.
    dim = new Dimension(800, 600);
    layout = new CardLayout();
    panel = new JPanel(layout);
    menu = new Menu();
    miniGame = new MiniGame();
    board = new Board(map);
    gameLayers = new JLayeredPane();

    //Remove decoration and place window in center of screen.
    setUndecorated(true);
    Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
    setBounds((screenDim.width /2)-(dim.width/2),
            (screenDim.height/2)-(dim.height/2),
            dim.width,
            dim.height);

    //Add the board to a layer.
    gameLayers.add(board, JLayeredPane.DEFAULT_LAYER);
    board.setBounds(0, 0, dim.width, dim.height);
    board.setBoard();

    //Add the sprite to a layer.
    gameLayers.add(sprite, JLayeredPane.PALETTE_LAYER);
    sprite.setBounds(0, 0, 50, 50);

    //Add components to window.
    panel.add(gameLayers, "gameLayers");
    panel.add(miniGame, "miniGame");
    panel.add(menu, "menu");

    //Add the "cards" to the window.
    add(panel);

    //JFrame housekeeping.
    pack();
    setSize(dim);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setResizable(false);
    setVisible(true);

    //Holds state when an event is triggered.
    //Ugly hack to circumvent delay issue.
    keys = new Boolean[4];
    for(int i=0; i<keys.length; i++){
        keys[i] = false;
    }
}
}

您如何推荐我接近这个?请记住,Board是一个JPanel,由一个缩放图像网格组成,精灵将是一个显示缩放图像的JComponent。

How would you recommend I approach this? Bearing in mind that the Board is a JPanel consisting of a grid of scaled images, and the sprite will be a JComponent displaying a scaled image.

问候,
杰克。

Regards, Jack.

推荐答案

覆盖JPanel的paintComponent()方法并将内容绘制成 BufferedImage 图像。完成后,将BufferedImage的内容复制到您从paintComponent()获得的图形上下文中。

Override the JPanel's paintComponent() Method and paint the content into a BufferedImage image first. Once done, copy the content of the BufferedImage into the graphics context you get from paintComponent().

protected void paintComponent(Graphics g) 
{
    BufferedImage bufferedImage = new BufferedImage(500, 500, BufferedImage.TYPE_ARGB);
    Graphics2D g2d = bufferedImage.createGraphics();
    //paint using g2d ...

    Graphics2D g2dComponent = (Graphics2D) g;
    g2dComponent.drawImage(bufferedImage, null, 0, 0);  
}

这篇关于双缓冲JFrame的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆