Applets Java
En esta página:
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.
|