java双缓冲问题

时间:2022-07-11 02:06:00

在编写Java多媒体动画程序或用Java编写游戏程序的时候,我们得到的动画往往存在严重的闪烁(或图片断裂),具体的方法是:

(1)定义一个Graphics对象gBuffer和一个Image对象iBuffer。按屏幕大小建立一个缓冲对象给iBuffer。然后取得iBuffer的Graphics赋给gBuffer。此处可以把gBuffer理解为逻辑上的缓冲屏幕,而把iBuffer理解为缓冲屏幕上的图象。

(2)在gBuffer(逻辑上的屏幕)上用paint(Graphics g)函数绘制图象。

(3)将后台图象iBuffer绘制到前台。

以上就是一次双缓冲的过程。注意,将这个过程联系起来的是repaint()函数。paint(Graphics g)是一个系统调用语句,不能由程序员手工调用。只能通过repaint()函数调用。

程序如下:

    import java.awt.*;
    import java.awt.event.*;
    
    public class DoubleBuffer extends Frame{
        private Image iBuffer;
        private Graphics gBuffer;
        PaintThread pt=null;
        int yPos=-80;
        public  DoubleBuffer(){
            pt=new PaintThread(this);
            this.setResizable(true);
            this.setSize(300,300);
            this.setVisible(true);
            pt.start();
            }
        public void paint(Graphics g){
            Color c=g.getColor();
            g.setColor(Color.RED);
            g.fillOval(90,yPos,80,80);
            }
        public void update(Graphics g){
            if(iBuffer==null){
                iBuffer=createImage(this.getSize().width,this.getSize().height);
                gBuffer=iBuffer.getGraphics();
                }
                gBuffer.setColor(getBackground());
                gBuffer.fillRect(0,0,this.getSize().width,this.getSize().height);
                paint(gBuffer);
                g.drawImage(iBuffer,0,0,this);
            }
        public static void main(String[] args){
            DoubleBuffer db=new DoubleBuffer();
            db.addWindowListener(new WindowAdapter(){
                public void windowClosing(WindowEvent e){
                    System.exit(0);
                    }
                });
            }
        }
    class PaintThread extends Thread{
        DoubleBuffer db=null;
        public PaintThread(DoubleBuffer db){
            this.db=db;
            }
        public void run(){
            while(true){
                try{
                Thread.sleep(30);    
            }catch(InterruptedException e){
                e.printStackTrace();
                }
            db.yPos+=5;
            if(db.yPos>300) db.yPos=-80;
            db.repaint();
                }
            }
        }