JAVA中的双缓冲问题

/** *//**
 *双缓冲
 *什么是重量级,轻量级
 *轻量级在这里指用纯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();
                }
            }
        }

    }
}
 

时间: 2024-10-26 17:28:32

JAVA中的双缓冲问题的相关文章

java中的双缓冲技术

毕业设计有个远程协助功能,得到对方的屏幕后,老是会闪,很是不爽,今天用java的双缓冲技术解决了.代码如下,本类重写了Swing中的JLabel,当Label重绘时,会默认的调用它的update方法,主要用于清除界面,然后update方法会调用paint方法,再把界面画上去,所以我现在update方法中创建了一个Image和Graphics对象Image off_screen_buf和off_screen_gc同时设置其大小和MyLabel对象的大小一样,用于把要画的东东先绘制到后台内存中,然后

【求助】关于Java中的双缓冲技术

问题描述 我尝试写一个人物行走的动画.我使用了双缓冲技术,但是屏幕仍然会闪烁,希望大家能够帮我找到其中的错误.代码如下:(1)精灵类packagesprite;importjava.awt.*;importjava.awt.image.*;importjavax.swing.*;publicclassSprite{publicintm_posX=0,m_posY=0;privateImagepic[]=null;privateintmPlayID=0;booleanmFacus=true;pub

基于WTL中使用双缓冲避免闪烁的解决方法_C 语言

在自己画的窗口中,有时候会有闪烁现象.为什么会有闪烁现象呢?其实是因为程序在画窗口时需要用背景色清空显示区域,然后再画.由于这两者的反差比较大,就会被人眼睛捕捉到,感觉闪烁.双缓冲就是先在内存中把图画好,然后直接复制到屏幕上去,这样的反差就比较小,也就不觉得闪烁了. WTL中的CDoubleBufferImplWTL中有现成的双缓冲类实现,可以很方便的使用就达到效果.CDoubleBufferImpl 在AtlFrame.h中.1.首先继承自CDoubleBufferImpl 复制代码 代码如下

Visual C++中实现双缓冲的基本原理

双缓冲的原理可以这样形象的理解:把电脑屏幕看作一块黑板.首先我们在内存环境中建立一个"虚拟"的黑板,然后在这块黑板上绘制复杂的图形,等图形全部绘制完毕的时候,再一次性的把内存中绘制好的图形"拷贝"到另一块黑板(屏幕)上.采取这种方法可以提高绘图速度,极大的改善绘图效果. 例如在OnDraw()函数中可以如下所述实现双缓冲,其主要步骤分为四步:       CPen Pen;       Pen.CreatePen(PS_INSIDEFRAME,1,RGB(225,2

Java中实现双数组Trie树实例_java

传统的Trie实现简单,但是占用的空间实在是难以接受,特别是当字符集不仅限于英文26个字符的时候,爆炸起来的空间根本无法接受. 双数组Trie就是优化了空间的Trie树,原理本文就不讲了,请参考An Efficient Implementation of Trie Structures,本程序的编写也是参考这篇论文的. 关于几点论文没有提及的细节和与论文不一一致的实现: 1.对于插入字符串,如果有一个字符串是另一个字符串的子串的话,我是将结束符也作为一条边,产生一个新的结点,这个结点新节点的Ba

JAVA中使用双括号来初始化静态常量的小技巧_java

这貌似是个不为人知的语言技巧.我看到一般人写Java里初始化静态常量都是 复制代码 代码如下: public static final Map<String, String> DATA = new TreeMap<String, String>(); static{ DATA.put("a", "A"); //blah blah blah} 使用所在类的static块来初始化DATA,其实还有另外一种写法: 复制代码 代码如下: public

双缓冲DoubleBuffered解决闪烁问题

一.使用默认的双缓冲 1 在应用程序中使用双缓冲的最简便的方法是使用 .NET Framework 为窗体和控件提供的默认双缓冲.通过将 DoubleBuffered 属性设置为 true.      this.DoubleBuffered=true; 2 使用 SetStyle 方法可以为 Windows 窗体和所创作的 Windows 控件启用默认双缓冲,在窗体或者控件的构造函数中添加如下代码即可: SetStyle(ControlStyles.ResizeRedraw,true); Set

[Qt教程] 第18篇 2D绘图(八)双缓冲绘图

[Qt教程] 第18篇 2D绘图(八)双缓冲绘图 楼主  发表于 2013-5-2 22:07:23 | 查看: 789| 回复: 1 双缓冲绘图 版权声明 该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 导语 在前面一节中,讲述了如何实现简单的涂鸦板,这一次我们将实现在涂鸦板上绘制图形,这里以矩形为例进行讲解.在后面还会提出双缓冲绘图的概念. 环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2 目录 一.绘制矩

双缓冲(Double Buffer)原理和使用【转】

转自:http://blog.csdn.net/acs713/article/details/16359551 原文出自:http://blog.csdn.net/xiaohui_hubei/article/details/16319249 一.双缓冲作用            双缓冲甚至是多缓冲,在许多情况下都很有用.一般需要使用双缓冲区的地方都是由于"生产者"和"消费者"供需不一致所造成的.这样的情况在很多地方后可能会发生,使用多缓冲可以很好的解决.我举几个常见