双缓冲绘图模式

reapaint()调用update()再调用paint();

所以在update中使用双缓冲

private Image offScreenImage = null;
    public void update(Graphics g) {
        if(offScreenImage == null)
            offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
        
        Graphics gOff = offScreenImage.getGraphics();

        paint(gOff);       
        g.drawImage(offScreenImage, 0, 0, null);
    }

//子类调用父类的launchFrame->PaintThread().strat()->repaint()->update(Graphics g)->paint(Graphic iB)===>g:原画布,iB:新画布
//update中有paint()方法,因为在子类中对该函数进行了覆盖,所以不调用父类中的paint(),而是子类中的paint(),而此时传给paint的参数是新的画布,

//而不是在原画布上直接操作,然后再把这个画布放到原来的画布上。这就形成了双缓冲绘图。

完整程序:

public class MyFrame  extends Frame {
    
    /**
     * 加载窗口
     */
    public void launchFrame(){
        setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
        setLocation(100, 100);
        setVisible(true);
        
        new PaintThread().start();  //启动重画线程
        
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    
    private Image offScreenImage = null;
    public void update(Graphics g) {
        if(offScreenImage == null)
            offScreenImage = this.createImage(Constant.GAME_WIDTH,Constant.GAME_HEIGHT);
        
        Graphics gOff = offScreenImage.getGraphics();
          
        paint(gOff);
        g.drawImage(offScreenImage, 0, 0, null);  
    }
    
    /**
     * 定义一个重画窗口的线程类,是一个内部类
     * @author dell
     *
     */
    class PaintThread extends Thread {
        
        public void run(){
            while(true){
                repaint();
                try {
                    Thread.sleep(40); //1s = 1000ms
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }   
            }
        }
        
    }
}
原文地址:https://www.cnblogs.com/xiaochi/p/4992842.html