Disegna una linea spezzata

Scrivere un applet che disegna una linea spezzata seguendo i click del mouse. In altre parole, ogni volta che si fa un click, va aggiunto un segmento fra l'ultimo punto della spezzata e quello in cui si trova il cursore.

Lasciamo da parte il problema di rendere permanente la spezzata, ossia di fare in modo che venga ridisegnata ogni volta che la finestra viene coperta e torna nuovamente visibile. Ci concentriamo invece sul problema del disegno.

Dal momento che si tratta di fare qualcosa ogni volta che si preme il pulsante del mouse, occorre scrivere qualcosa nella procedura mouseDown. In particolare, occorre disegnare un segmento fra l'ultimo punto disegnato e quello in cui si trova il cursore in questo momento. La posizione attuale del cursore è memorizzata in x e y come al solito. Serve anche sapere la posizione del penultimo punto in cui il pulsante era stato premuto. Occorre quindi che la procedura stessa salvi la posizione in due variabili globali, in modo tale che la volta dopo di sappia la posizione precedente.

La funzione mouseDown è quindi fatta in questo modo (per ora):

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

    g.drawLine(xultimo,yultimo,x,y);

    xultimo=x;
    yultimo=y;

    return true;
  }
Le due variabili xultimo e yultimo sono dichiarate come variabili globali. Resta ancora un punto da decidere: quale valore iniziale devono avere queste due variabili? Se mettiamo per esempio 0 in entrambe, abbiamo che il primo punto della spezzata si trova sempre nella posizione (0,0). D'altra parte, noi vorremmo far partire la spezzata nel punto in cui il pulsante è stato premuto per la prima volta.

Il problema si risolve facilmente considerando che, la prima volta che il pulsante viene premuto, non occorre disegnare nessuna linea: infatti, questo è il punto iniziale della spezzata; la prima linea sarà fra questo punto e il successivo. Il problema, a questo punto, è: come facciamo, all'interno di mouseDown a capire se stiamo al primo click del mouse oppure no? Il problema non è difficile come sembra.

Supponiamo di mettere -1 come valore iniziale di xultimo. Quando mouseDown viene eseguito per la prima volta, xultimo vale quindi -1. In questa variabile viene poi messa la coordinata x del punto attuale del cursore, che è un numero maggiore o uguale a 0. Alla successiva chiamata, nella variabile c'è ancora questo valore, che viene poi modificato nuovamente con la nuova coordinata. Si può quindi dire che la variabile vale -1 soltanto la prima volta che la procedura viene eseguita, ossia soltanto la prima volta che viene premuto il pulsante del mouse.

Questo ci permette di decidere se disegnare o no la linea. Come si è detto, la linea va disegnata soltanto se questa non è la prima volta che il pulsante è stato premuto. Abbiamo visto che xultimo vale -1 soltanto la prima volta che il pulsante è stato premuto. Quindi, la linea va fatta solo se xultimo non vale -1.

Il programma finale DisegnaSpezzata.java contiene la procedura mouseDown modificata, in cui la linea viene disegnata solo se xultimo ha un valore diverso da -1.

/*
  Disegna un poligono, dati i punti successivi
*/

import java.awt.*;

public class DisegnaSpezzata extends java.applet.Applet {
  int xultimo=-1, yultimo=-1;

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

    if( xultimo != -1 ) {
      g.drawLine(xultimo,yultimo,x,y);
    }

    xultimo=x;
    yultimo=y;

    return true;
  }
}