pip13.gif (3136 bytes)

Eliminare il lampeggiamento: doppia bufferizzazione.

Il lampeggiamento nell'applet precedente è causato dal fatto che il programma cancella   e ridisegna l'immagine sullo schermo con grande frequenza. Una soluzione consiste nel disegnare al di fuori dello schermo, nella memoria temporanea, e, alla fine, una volta completata la nuova immagine, con un unico passaggio, la si copierà dalla memoria temporanea sullo schermo: questa è la tecnica della doppia bufferizzazione.

Bisogna quindi creare un oggetto Graphics delle stesse dimensioni della finestra dell'applet, questo nuovo oggetto Graphics, che abbiamo chiamato mioschermo, è lo spazio di memoria temporanea nel quale disegnare. Abbiamo anche bisogno di un oggetto Image, che abbiamo chiamato miaIm, dove registrare tutto quello che è stato disegnato nella zona invisibile (la memoria temporanea). Questi oggetti sono dichiarati nel metodo init().

miaIm = createImage(getSize().width, getSize().height);

crea un'immagine vuota delle dimensioni dell'applet.

mioschermo = miaIm.getGraphics();

associa mioschermo a miaIm tramite il metodo getGraphics() della classe Image.

Quando le operazioni di disegno sono completate si può passare l'immagine sullo schermo dell'applet con:

screen.drawImage(miaIm, 0, 0, this);

(siccome miaIm ha le stesse dimensioni della finestra dell'applet, possiamo usare le coordinate (0,0)).

Ecco il codice modificato dell'esempio precedente:

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

public class ArcoB extends Applet implements Runnable {

int a = 10;
Color colore;
Thread runner;
Image miaIm;
Graphics mioschermo;


//init
public void init() {
setBackground(Color.orange);
colore = new Color(0,0,0);
miaIm = createImage(getSize().width, getSize().height);
mioschermo = miaIm.getGraphics();
    }
public void paint (Graphics screen) {
    mioschermo.setColor(colore);
    mioschermo.fillArc(90,70,100,100,0,a);
    screen.drawImage(miaIm, 0, 0, this);
    }
//start
public void start() {
if(runner == null) {
    runner = new Thread(this);
    runner.start();
    }
}
//run
public void run() {
Thread thisThread = Thread.currentThread();
while(runner == thisThread) {
    if(a < 360) {
    a = a+10;
    repaint();
        }
    else {
    colore = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
    repaint();
    a = 10;
    }
try {
    Thread.sleep(10);
} catch(InterruptedException e) { }
}
}
//stop
public void stop() {
if(runner != null) {
    runner = null;
    }
}
public void update(Graphics screen) {
    paint(screen);
    }
}

il cui risultato è:

 

Il lampeggiamento è scomparso.

fleche_retour.gif (1377 bytes)avanti02.gif (9574 bytes)