Java Swing 雙緩衝技術解決映像閃爍問題__java

來源:互聯網
上載者:User
參考內容:關於雙緩衝

       我們看電視時,看到的螢幕稱為OSD層,也就是說,只有在OSD層上顯示映像我們才能看到。現在,我需要建立一個虛擬、看不見但是可以在上面畫圖(比如說畫點、線)的OSD層,我稱之為offscreen(背景緩衝區)。這個offscreen存在於記憶體中,我們在上面畫圖,這個offscreen上面的東西可以顯示在OSD層上,需要一個建立這個offscreen的函數,返回這個offscreen的控制代碼(整型指標)、寬度、高度、指向建立offscreen資料緩衝區的指標,該緩衝區是一個在函數外建立的offscreen的資料緩衝區,大小是offscreen的高度*寬度*每個像素點資料的大小。閃爍是圖形編程的一個常見問題。需要多重複雜繪製操作的圖形操作會導致呈現的映像閃爍或具有其他不可接受的外觀。雙緩衝的使用解決這些問題。雙緩衝使用記憶體緩衝區來解決由多重繪製操作造成的閃爍問題。當啟用雙緩衝時,所有繪製操作首先呈現到記憶體緩衝區,而不是螢幕上的繪圖圖面。所有繪製操作完成後,記憶體緩衝區直接複製到與其關聯的繪圖圖面。因為在螢幕上只執行一個圖形操作,所以消除了由複雜繪製操作造成的映像閃爍。

在Java swing中,繪製的原理如下:

update() -> paint(Graphics g) -> paintComponent(Graphics g)

       它們是逐漸調用的,Java swing內建有雙緩衝,在paint(Graphics g)中。

       假如我們的映像繪製在JPanel上,我們可以繼承JPanel,然後複寫裡面的paintComponent(Graphics g)和update方法。我們可以在paintComponent上繪製映像,然後調用paint方法就可以調用paintComponent方法繪製映像。

 

 雙緩衝的實現:

        複寫JPanel類中的update()方法,建立一個映像緩衝空間,然後把它的畫筆拿過來,用paint方法把要繪製的東西繪製上去。再一次性把映像顯示在JPanel控制項上。

       我在這裡是用滑鼠畫線消除閃動的例子來說明雙緩衝的使用。

import java.awt.Canvas;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionAdapter;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.awt.image.BufferedImage;import javax.swing.JFrame;public class DrawTrail{ BufferedImage image = new BufferedImage(500, 500,   BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); private DrawCanvas canvas = new DrawCanvas(); private int preX = -1; private int preY = -1;    private Image offScreenImage;  //圖形緩衝     public void init() {  g.fillRect(0, 0, 1600, 1000);  JFrame frame = new JFrame("測試畫出滑鼠的軌跡");  frame.setSize(600, 600);    frame.add(canvas);  frame.setLayout(null);  canvas.setBounds(0, 0, 500, 500);  frame.setVisible(true);    canvas.addMouseMotionListener(new MouseMotionAdapter()  {   @Override   public void mouseDragged(MouseEvent e)   {    if (preX > 0 && preY > 0)    {     g.setColor(Color.black);     g.drawLine(preX, preY, e.getX(), e.getY());    }    preX = e.getX();    preY = e.getY();    canvas.repaint();   }  });    frame.addWindowListener(new WindowAdapter()//添加視窗關閉處理函數     {            public void windowClosing(WindowEvent e)            {               System.exit(0);            }}); }  public static void main(String[] args) {  DrawTrail dc = new  DrawTrail();  dc.init();   }  class DrawCanvas extends Canvas {  private static final long serialVersionUID = 1L;  @Override  public void paint(Graphics g)  {   Graphics2D g2 = (Graphics2D)g;   g2.drawImage(image, 0, 0, null);  }    @Override  public void update(Graphics g)  {         if(offScreenImage == null)            offScreenImage = this.createImage(500, 500);     //建立一個映像緩衝空間,這裡映像大小為800*600            Graphics gImage = offScreenImage.getGraphics();  //把它的畫筆拿過來,給gImage儲存著            paint(gImage);                                   //將要畫的東西畫到映像緩衝空間去            g.drawImage(offScreenImage, 0, 0, null);         //然後一次性顯示出來  } }}


       

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.