Sposta una figura

Il problema da risolvere è questo: scrivere un applet che disegna un quadratino riempito in ogni punto in cui si preme il pulsante del mouse; inoltre, quando si preme di nuovo il pulsante, va disegnato un nuovo rettangolo, ma il precedente va cancellato.

Questo programma è completamente centrato intorno alla funzione mouseDown. Infatti, le uniche operazioni da fare sono:

Disegnare il quadrato nella nuova posizione è facile: basta mettere l'istruzione g.drawRect(x-5,y-5,10,10) dentro mouseDown.

La cosa più complicata è cancellare il quadrato che era stato disegnato in precedenza. Per fare questo è necessario, ogni volta che si disegna un quadrato, memorizzare la sua posizione, in modo tale che al click successivo il quadrato si possa cancellare. Quindi, occorre salvare i valori di x e y in modo che siano disponibili la successiva volta che si preme il pulsante.

Un metodo che a prima vista può sembrare valido è questo:

  public boolean mouseDown(Event e, int x, int y) {
    Graphics g=getGraphics();
    int xultimo, yultimo;		/* PROGRAMMA ERRATO */

    g.clearRect(xultimo-5,yultimo-5,10,10);

    g.fillRect(x-5,y-5,10,10);

    xultimo=x;
    yultimo=y;

    return true;
  }
In effetti, in questa funzione i valori di x e y vengono memorizzati nelle variabili xultimo e yultimo; alla successiva chiamata, viene cancellato il quadratino messo in questa posizione. Questo sistema non funziona perchè vale la seguente regola:

quando una procedura termina, il contenuto delle sue variabili locali viene cancellato.
Nel nostro caso, quando viene premuto il pulsante, i valori di x e y vengono copiati nelle variabili xultimo e yultimo, però queste due variabili vengono cancellate quando si arriva alla fine della procedura mouseDown. Al successivo click del mouse non sarà più possibile cancellare il quadratino precedente.

Visto che la variabili locali vengono cancellate alla fine della esecuzione della procedura, l'unico altro metodo che abbiamo per memorizzare in modo permanente questi valori è quello di copiarne il valore in due variabili globali. Definiamo quindi xultimo e yultimo come variabili globali. Ogni volta che si preme il pulsante del mouse, i valori di x e y vengono copiati in queste due variabili. Dal momento che xultimo e yultimo sono globali, il loro valore non viene cancellato quando mouseDown finisce (la cancellazione avviene solo per le variabili locali). Quindi, la volta dopo che il pulsante viene premuto, le variabili globali contengono ancora la posizione del quadrato precedente. È quindi possibile cancellarlo.

Riassumendo, la funzione mouseDown è fatta cosí: per prima cosa si cancella il quadrato precedente, poi si disegna il quadrato nuovo, e poi si memorizza la posizione nelle variabili globali. Manca ora solo da dire i valori iniziali delle variabili globali. Infatti, la prima volta che si esegue mouseDown viene comunque fatta l'operazione di cancellazione del quadrato posizionato in xultimo e yultimo, e quindi viene fatta la cancellazione di un quadrato le cui coordinate sono date dai valori iniziali di queste variabili. Possiamo scegliere di dare inizialmente -10 a xultimo e yultimo, in modo tale che la cancellazione avvenga fuori dall'area visibile della finestra.

Il programma completo Sposta.java risulta quindi fatto nel modo seguente:

/*
  Sposta il rettangolo nel punto in cui viene premuto
  il pulsante.
*/

import java.awt.*;

public class Sposta extends java.applet.Applet {
  int xultimo=-10, yultimo=-10;

  public boolean mouseDown(Event e, int x, int y) {
    Graphics g=getGraphics();

    g.clearRect(xultimo-5,yultimo-5,10,10);

    g.fillRect(x-5,y-5,10,10);

    xultimo=x;
    yultimo=y;

    return true;
  }
}