Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2009-2010.

LABORATORIO - INTERFACCE GRAFICHE IN JAVA

Contesto generale

Riprendiamo l'esercizio del laboratorio guidato scorso dove abbiamo caricato un'immagine e l'abbiamo visualizzata.
(era chiesto anche di disegnare un poligono sull'immagine, se non lo avete fatto saltatelo pure perche' ora lo rifaremo acquisendo i vertici dall'utente).

In questo laboratorio permetteremo all'utente di disegnare un poligono usando il mouse.

Al solito, procederemo per gradi...

Grado 1: Disegno del poligono

Questa fase richiede di fare delle scelte progettuali, percio' fermatevi a pensare prima di iniziare a scrivere codice.
La parte che segue spiega quali scelte sono in gioco...

L'utente immettera' il poligono un vertice per volta.
Finche' il poligono non e' stato chiuso, di fatto non esiste un poligono ma una linea spezzata non chiusa, i cui segmenti uniscono ogni coppia consecutiva di punti gia' inseriti.
Inoltre e' necessario dare riscontro all'utente di dove sta tracciando il prossimo segmento: quindi ci sara' anche il segmento che unisce l'ultimo punto inserito alla posizione attuale del mouse (a differenza degli altri segmenti, che sono definitivi, questo e' provvisorio).
Il poligono si chiude quando l'utente il nuovo punto inserito dall'utente cade "abbastanza vicino" al primo punto, da poter essere considerato coincidente con esso.
Inoltre ci dovra' essere un modo per annullare il poligono senza averlo concluso.

Le azioni che sono richieste all'utente nelle varie tappe del disegno dovete deciderle voi.
Per esempio potete decidere che l'utente metta i vertici col click del mouse, lo spostamento da un vertice al successivo avvenga col mouse non premuto, e che annulli il poligono con un tasto funzione (es. ESC).
Ma potete fare anche altre scelte...

Sicuramente avrete bisogno di associare al pannello almeno un mouse listener (per catturare l'immissione di un vertice, da cui dipende la creazione dei segmenti "definitivi") e un mouse motion listener (per catturare il movimento del mouse da cui dipende il segmento "provvisorio").

Ricordate che:

La situazione attuale e' rappresentata da:

Potete memorizzare i vertici nel modo che desiderate:
Due array per le x e le y (conformemente a quanto richiedono in argomento le funzioni drawPolyline e drawPolygon della chasse Graphics), ricordate di memorizzare anche il numero di vertici inseriti.
Oppure direttamente un oggetto di classe Polygon (come poi richiesto nel progetto per preparare un'immagine dal quad-tree), ma in questo caso ricordate che finche' il poligono non e' chiuso va disegnato non il poligono bensi' i singoli segmenti.
O altre scelte...

Adesso dovete fare le scelte progettuali:
che azioni richiedere all'utente?
come memorizzare la situazione attuale?
Decidete questo prima di iniziare a scrivere il codice...

Nella paintComponent del pannello aggiungete le chiamate necessarie al disegno. Perche' venga disegnato sopra l'immagine, e' sufficiente metterle dopo il disegno dell'immagine.

Nelle callback invece mette i comandi necessari a modificare la situazione attuale, e la chiamata a repaint.

Ricordate che:

Grado 2: Zoom del poligono

Quanto fatto sopra vale nella situazione con fattore di zoom uguale a 1.
Se il fattore di zoom e' diverso da 1, occorre garantire che la situazione corrente venga memorizzata a zoom = 1, e il fattore di zoom intervenga solo nella funzione paintComponent per il disegno. Questo serve ad evitare pasticci se il poligono viene acquisito con un certo zoom e poi lo zoom viene cambiato.

In pratica: