Usar un BufferedImage para Doble Buffer
Cuando un gráfico es complejo o se usa repetidamente, podemos reducir el tiempo que tarda
en mostrarse renderizándolo primero en un buffer fuera de pantalla y luego copiando el
buffer en la pantalla. Esta técnica, llamada doble buffer, se usa
frecuentemente para animaciones.
|
Nota:
Cuando dibujamos sobre un componente Swing, éste utiliza automáticamente el doble buffer.
|
Un BufferedImage puede usarse fácilmente como un buffer fuera de
pantalla. Para crear un BufferedImage cuyo espacio, color,
profundidad y distribución de pixels corresponden exactamente la ventana en la que son
dibujados, se llama al método Component.
createImage. Si necesitamos control sobre el tipo de la imagen fuera de la
pantalla, la transparencia, podemos construir directamente un objeto
BufferedImage y usarlo como un buffer.
Para dibujar dentro de una imagen almacenada, se llama al método
BufferedImage.createGraphics para obtener el objeto
Graphics2D; luego se llama a los métodos de dibujo apropiados del
Graphics2D. Todo el API de dibujo de Java 2D puede usarse cuando se dibuja
sobre un BufferedImage que está siendo utilizado como un buffer
fuera de pantalla.
Cuando estemos listos para copiar el BufferedImage en la pantalla,
simplemente llamamos al método drawImage sobre el
Graphics2D de nuestro componente y pasarlo en
BufferedImage.
Ejemplo: BufferedShapeMover
El siguiente applet permite al usuario arrastrar un rectángulo sobre la ventana del
applet. En lugar de dibujar el rectángulo en cada posición del cursor, para proporcionar
información al usuario, se usa un BufferedImage como buffer fuera de
la pantalla. Cuando se arrastra el rectángulo, es renderizado dentro del
BufferedImage en cada nueva posición y el BufferedImage se
copia en la pantalla.
Esta es una imagen del GUI del applet. Para ajecutar el applet, pulsa
sobre ella. El applet aparecerá en una nueva ventana del navegador.
El código completo del applet está en
BufferedShapeMover.java.
Aquí está el código usado para renderizar en el BufferedImage y
mostrar la imagen en la pantalla.
public void updateLocation(MouseEvent e){
rect.setLocation(last_x + e.getX(),
last_y + e.getY());
...
repaint();
...
// In the update method...
if(firstTime) {
Dimension dim = getSize();
int w = dim.width;
int h = dim.height;
area = new Rectangle(dim);
bi = (BufferedImage)createImage(w, h);
big = bi.createGraphics();
rect.setLocation(w/2-50, h/2-25);
big.setStroke(new BasicStroke(8.0f));
firstTime = false;
}
// Clears the rectangle that was previously drawn.
big.setColor(Color.white);
big.clearRect(0, 0, area.width, area.height);
// Draws and fills the newly positioned rectangle
// to the buffer.
big.setPaint(strokePolka);
big.draw(rect);
big.setPaint(fillPolka);
big.fill(rect);
// Draws the buffered image to the screen.
g2.drawImage(bi, 0, 0, this);
}