雙緩衝編程

**
 *雙緩衝
 *什麼是重量級,輕量級
 *輕量級在這裏指用純java實現的。重量級指和其他語言混合編程,這樣耗用的資源多系統觸發的繪畫操作
 *繪畫操作的分類
 *系統觸發的和程序觸發的繪畫操作
 *AWT的繪製與界面更新使用了一個單獨的線程,稱爲AWT線程。這個線程可以在兩種情形下更新顯示。
 *一種情況是界面“顯露”,這可能會發生在界面首次顯示時,或者界面某一部分由於被其它窗口遮蓋後重新顯示時。界面顯露的處理是AWT自動進行的,。
 *第二種情況是程序在顯示內容有所改變時進行界面的更新,而這一般是由應用程序的邏輯來控制的。
 *
 *repaint() update()paint()
 *當我們應用程序的邏輯要對系統界面進行更新時,調用repaint() 方法來通知AWT線程進行刷新操作。repaint() 方法實際會讓AWT線程去調用另外一個方法,update。update方法在默認情況下會做兩件事,一是清除當前區域內容,二是調用其paint()方法完成實際繪製工作。
 *第一個優化工作就是重寫update() 方法,也就是不對當前區域進行清除工作,而直接進行繪製.
 *paint(g)中的g代表屏幕對象,直接對代表屏幕對象的Graphics對象進行操作,而這個操作是比較費時的操作。解決的辦法是採用“雙緩衝”,即我們創建一個繪製緩衝區,以bufImage表示,先將主要的圖形元素一個一個地繪製到此緩衝圖像上,再將此緩衝圖像一次性繪到代表屏幕的Graphics對象,即paint() 方法傳入的“g”上。
 *
 *paint(g);直接對代表屏幕對象的Graphics 對象進行操作,而這個操作是比較費時的操作。
 *重寫update()步驟:
 *得到緩衝圖象this.offScreenImage = this.createImage(800,600);
 *看APIcreateImage用來創建一幅用於雙緩衝的、可在屏幕外繪製的圖像。
 *得到緩衝圖象的畫筆Graphics offg = this.offScreenImage.getGraphics();
 *繪製緩衝圖象offg.setColor(Color.GREEN);
 *調用paint(),將緩衝圖象的畫筆傳入
 *再將此緩衝圖像一次性繪到代表屏幕的Graphics對象,即該方法傳入的“g”  上. g.drawImage(offScreenImage, 0, 0, null);
    *雙緩衝問題只在AWT中存在,spring中已解決
 */
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TankClient extends Frame ...{

    private static final long serialVersionUID = 1L;
    private int X = 50, Y = 50;
    private int GAME_WIDTH = 800;
    private int GAME_HEIGHT = 600;
    private Image offScreenImage;

    public static void main(String[] args) ...{
        TankClient tc = new TankClient();
        tc.launchFrame();
    }

    @Override
    public void update(Graphics g) ...{
        //1.得到緩衝圖像
        if(this.offScreenImage == null) ...{
            this.offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
        }
        //2.得到緩衝圖像的畫筆
        Graphics gOffScreen = this.offScreenImage.getGraphics();
        //3.繪製緩衝圖像
        Color c = gOffScreen.getColor();
        gOffScreen.setColor(Color.GREEN);
        gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
        gOffScreen.setColor(c);
        //4.調用paint(),將緩衝圖象的畫筆傳入
        paint(gOffScreen);
        //5.再將此緩衝圖像一次性繪到代表屏幕的Graphics對象,即該方法傳入的“g”上
        g.drawImage(offScreenImage, 0, 0, null);
    }

    @Override
    public void paint(Graphics g) ...{
        Color c = g.getColor();
        g.setColor(Color.RED);
        g.fillOval(X, Y, 30, 30);
        g.setColor(c);
        Y += 5;
    }

    public void launchFrame() ...{
        this.setBounds(100, 100, GAME_WIDTH, GAME_HEIGHT);
        this.setBackground(Color.GREEN);
        this.addWindowListener(new WindowAdapter() ...{
            public void windowClosing(WindowEvent e) ...{
                setVisible(false);
                System.exit(0);
            }
        });
        this.setTitle("TankWar");
        this.setResizable(false);
        this.setVisible(true);
        new Thread(new PaintThread()).start();
    }

    class PaintThread implements Runnable ...{

        public void run() ...{
            while (true) ...{
                repaint();
                try ...{
                    Thread.sleep(50);
                } catch (InterruptedException e) ...{
                    e.printStackTrace();
                }
            }
        }

    }
}

發佈了26 篇原創文章 · 獲贊 7 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章