Applets Java


En esta p�gina:

  • T�cnica Double-buffering

T�cnica Double-buffering

Ejecutando el ejemplo del cap�tulo anterior, podemos observar un parpadeo mientras el texto avanza hacia la izquierda. Esto es debido al modo que tiene Java de actualizar la imagen que vemos del applet.

Cuando llamamos al m�todo repaint(), �ste se encarga de llamar a update(), el cual borra lo que haya en el applet y llama a paint() para pintarlo de nuevo. Y todo eso lo contemplan nuestros ojos. El parpadeo es debido a que nuestro ojo se da cuenta de que hemos borrado la pantalla y que tardamos cierto tiempo en escribir de nuevo el texto.

Para remediarlo existe un t�cnica llamada double-buffering. Esta t�cnica no es exclusiva de Java, pues por ejemplo muchos de los juegos que utilizamos la implementan, o incluso utilicen t�cnicas m�s complicadas. Este m�todo consiste en construir una pantalla virtual, que no vemos pero que existe en la memoria del ordenador, y pintar en ella lo que necesitemos mostrar para volcarla a la pantalla real cuando lo necesitemos.

Eso elimina nuestros dos problemas. Primero, no borramos nunca la pantalla, sino que la sustituimos, por lo que la retina no aprecia que se quede en blanco en ning�n momento. Segundo, el volcado es un proceso muy r�pido, por lo que no se pueden apreciar que la pantalla virtual se ha volcado s�lo un cachito pero otro no como suced�a cuando dibuj�bamos directamente.

Para implementar esta t�cnica, deberemos tener en cuenta que Graphics es una clase abstracta, por lo que no podemos utilizarla para crear esa pantalla virtual. En cambio, utilizaremos Image, que dispone de un m�todo que nos ser� muy �til en este caso:

Graphics img.getGraphics()
Este m�todo crear� un lienzo a partir de una imagen, con las mismas dimensiones que �sta.

Tambi�n utilizaremos el m�todo de Applet llamado createImage(anchura, altura) que crea una imagen en blanco del tama�o especificado. As� pues, vamos a modificar nuestro famoso ejemplo, ennegreciendo de nuevo el c�digo nuevo que interviene en la implementaci�n en Java de la t�cnica double-buffering:

MostrarCadena.java
/**
 * Applet MostrarCadena
 *
 * <APPLET CODE="MostrarCadena.class" WIDTH="200" HEIGHT="70">
 *   <PARAM NAME="Cadena" VALUE="Esto s� que es chulo">
 * </APPLET>
 */

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

public class MostrarCadena extends Applet implements Runnable {
  String mensaje;
  int lugar, ancho, alto;
  Thread hilo = null;
  Image buffer;
  Graphics pantallaVirtual;
  public void init() {
    mensaje = getParameter("cadena");
    if (mensaje==null)
      mensaje = "Mensaje por defecto";
    ancho = getBounds().width;
    alto = getBounds().height;
    lugar = ancho;
    buffer = createImage(ancho, alto);
    pantallaVirtual = buffer.getGraphics();
  }
  public void start() {
    if (hilo==null) {
      hilo = new Thread(this);
      hilo.start();
    }
  }
  public void stop() {
    hilo = null;
  }
  public void paint(Graphics g) {
    g.drawString(mensaje,lugar,20);
  }
  public void update(Graphics g) {
    Color colorTemporal = pantallaVirtual.getColor();
    pantallaVirtual.setColor(Color.white);
    pantallaVirtual.fillRect(0, 0, ancho, alto);
    pantallaVirtual.setColor(colorTemporal);
    paint(pantallaVirtual);
    g.drawImage(buffer, 0, 0, this);
  }
  public void run() {
    while (hilo!=null && hilo.isAlive()) {
      lugar -= 1;
      repaint();
      try {
        hilo.sleep(10);
      }
      catch (InterruptedException e) { // No hacemos nada
      }
    }
  }
}

Inicializamos los dos nuevos objetos necesarios para implementar esta t�cnica en el m�todo init() utilizando como tama�o de la imagen y su lienzo asociado el del applet. Este tama�o lo averiguamos por medio de una llamada a getBounds().

El proceso de implementar la t�cnica se realiza en la sobreescritura del m�todo update(). Este m�todo recibe como par�metro el lienzo correspondiente al rect�ngulo que ocupa el applet en la pantalla. Sin embargo, lo que hace es limpiar el lienzo de la pantalla virtual y llama a paint utilizando como par�metro este �ltimo lienzo, por lo que paint() dibuja en la pantalla virtual. Por �ltimo, vuelca el buffer en la pantalla real.

Esto �ltimo es posible debido a que buffer y pantallaVirtual son referencias que apuntan a objetos que en realidad representan lo mismo. De modo que todo lo que hagamos al lienzo pantallaVirtual se ve reflejado en la imagen buffer y viceversa.