##
DOBLE-BUFFERING DE GRAFICOS

Al mostrar gráficos con las técnicas estándar, las imágenes suelen aparecer a trozos o con parpadeo. Las aplicaciones Java permiten que los programas dibujen en memoria, para luego ir mostrando la imagen completa de forma suave.

Este es el proceso conocido como doble-buffering, y tiene dos ventajas fundamentales sobre el proceso normal de pintar o dibujar directamente sobre la pantalla:

Primero, el usuario ve aparecer de golpe la imagen en la pantalla. Mientras el usuario está viendo esa imagen, el programa está generando la siguiente para mostrarla de golpe a continuación, y así una y otra vez.

Segundo, la técnica de doble-buffering involucra un objeto Image, que se puede pasar directamente a varios métodos. Esta capacidad para manipular objetos Image permite descomponer las rutinas de dibujo en componentes funcionales, en lugar de un enorme método paint().

No obstante, el doble-buffering sólo debe usarse para animaciones gráficas, no como método normal. Lo usual en otras aplicaciones sería repintar la zona que interese solamente.

### Contextos gráficos

Para entender el doble-buffering, primero se necesita comprender qué es un contexto gráfico. Un contexto gráfico es simplemente una estructura de datos que el sistema sabe utilizar como tablero de dibujo, es decir, es la zona en que se va a pintar. Ya hemos visto y utilizado contextos gráfico en las declaraciones del método paint():

    public void paint( Graphics g ) {

El objeto Graphics `g` es el contexto gráfico. Se utiliza `g` para realizar todo el dibujo en el applet. Por ejemplo:

    g.drawString( "¡Hola!",25,25 );
    g.drawRect( 15,15,50,10 );

Entonces, Java traduce todo lo que se dibuja en `g` en imágenes sobre la pantalla. Para realizar doble-buffering, se necesita pues, primero crear un contexto gráfico que no es presentado inmediatamente en la pantalla.

### Creación de Contextos Gráficos

Crear contextos gráficos tiene dos pasos: Crear una imagen vacía con las dimensiones adecuadas y obtener un objeto Graphics de esa imagen. El objeto Graphics que se construye en el segundo paso realiza la función de contexto gráfico.

Por ejemplo, CGrafico.java:

    import java.awt.*;
    import java.applet.Applet;

    public class CGrafico extends Applet {
        Image dobleBuffer;
        Graphics miCG;

        public void init() {
            // Inicializa el doble buffer
            dobleBuffer = createImage( 300,300 );
            miCG = dobleBuffer.getGraphics();

            // Construye un área gráfica de trabajo
            miCG .setColor( Color.white );
            miCG.fillRect( 0,0,300,300 );
            resize( 500,450 );
            }

Podemos utilizar `miCG` para dibujar cualquier cosa. Las imágenes se trazarán en doble buffer. Cuando el dibujo esté terminado, se puede presentar el doble buffer en pantalla:

    public void paint( Graphics g ) {
        // Sólo se tiene que presentar la imagen del buffer
        g.drawImage( dobleBuffer,0,0,this );
        }

### Utilización de Contextos Gráficos

Una vez definido un contexto gráfico, podemos usarlo en cualquier parte de nuestro programa. Por ejemplo, podemos repartir la responsabilidad para dibujar sobre varias funciones:

    public void titulo() {
        // Obtiene la fuente de texto actual y la guardamos
        Font f = miCG.getFont();

        // Seleccionamos otra fuente para el título
        miCG.setFont( new Font( "TimesRoman".Font.BOLD,36 ) );
        miCG.drawString( "Ejemplo de Espiral",15,50 );
        miCG.drawString( "Círculos",15,90 );
        // Recuperamos la fuente original
        miCG.setFont( f );
        }

    public void espiral() {
        int x,y;

        // Dibujamos circulos en los lados horizontales
        y = 100;
        for( x=100; x <= 200; x+=10 )
            {
            miCG.drawOval( x,y,20,20 );
            miCG.drawOval( x,y+100,20,20 );
            }
        // Ahora en los verticales
        x = 100;
        for( y=100; y <= 200; y+=10 )
            {
            miCG.drawOval( x,y,20,20 );
            miCG.drawOval( x+100,y,20,20 );
            }
        }

    public void start() {
        // Hace el dibujo off-line
        titulo();
        espiral();
        // Ahora muestra la imagen de golpe
        repaint();
        }

|  | ##### [Anterior] [Indice] [Siguiente]