Vedere dispense capitolo "Introduzione alle interfacce utente".
Vedere dispense capitolo "Finestre, eventi e loro gestione".
Qui probabilmente era poco chiara sulle dispense una cosa. Abbiamo detto che ci sono due possibilita': o se ne incarica il server oppure il client.
Vedere dispense capitolo "Introduzione alla Computer Graphics".
Per le trasformazioni di base in Java, vedere dispense capitolo "Grafica bi-dimensionale in Java".
Per il resto, vedere
dispense capitolo "Introduzione alla Computer Graphics".
Non erano richieste le matrici.
Qui un errore comune e' stato citare la scalatura e la rotazione
nel caso generale, mentre quelle di base sono la
scalatura con punto fermo l'origine e la rotazione intorno
all'origine.
Se cosi' non fosse, non si capirebbe il senso dell'ultima domanda
(come si ottiene una rotazione attorno a un punto generico -
se fosse disponibile come trasformazione di base la risposta sarebbe
banale).
Altra cosa: parecchi hanno descritto le trasformazioni anche nel caso 3D. Java ha grafica solo 2D, quindi il 3D non si applica. Nella correzione questo non e' stato contato.
Un modo e':
In questo modo il maggiore spazio in assoluto e' dedicato all'area
di disegno (che si trova in CENTRO di entrambi i
contenitori che lo contengono - risalendo la gerarchia
di annidamento).
E nell'area a destra il maggiore spazio e' dedicato allo
slider (perche' e' al CENTRO).
Nota: NON si poteva realizzare con BorderLayout e un unico livello di annidamento: si sarebbe ottenuto
+-----------+---+ | | | | | | | | | | | | +-----------+---+ | | +---------------+invece che
+-----------+---+ | | | | | | | | | | | | +-----------+ | | | | +-----------+---+
Alcuni hanno usato dei GridLayout: hanno messo una griglia a 1 riga e
2 colonne nella finestra principale, contenente due pannelli;
nel pannello a sinistra hanno messo una griglia a 1 colonna e 2 righe
con l'area di disegno e il bottone;
nel pannello a destra hanno messo una griglia a 1 colonna e 3 righe
con etichetta, slider e altra etichetta.
Ma attenzione: tutti gli elementi di una griglia hanno stesse dimensioni!
In questo modo vincoliamo l'area grafica ad avere le stesse dimensioni
del bottone (mentre ragionevolmente e' meglio averla piu' grande)
e vincoliamo lo slider ad essere grande come ciascuna delle due
etichette (mentre ragionevolmente e' meglio averlo piu' grande).
Inoltre la parte dedicata ad area grafica + bottone risulta grande
uguale alla parte dedicata a slider + etichette (mentre ragionevolmente e'
meglio avere la prima piu' grande della seconda).
Un errore di fondo che hanno fatto in molti e' quello di confondere la parte di ridisegno con la parte di callback:
La funzione di ridisegno deve disegnare lo stato attuale,
come descritto dalle variabili di stato.
NON deve modificare le variabili di stato!
In altre parole deve essere senza "side effect".
Questo perche' puo' dover essere chiamata piu' volte di seguito
(tutte le volte che la finestra va ridisegnata perche' viene
deiconificata o viene tolta una finestra che la oscurava
o viene redimensionata) e deve produrre sempre lo stesso effetto.
Inoltre la funzione di disegno NON prende come input degli eventi.
Nota: la funzione di ridisegno e' la stessa della funzione di
refresh dell'esercizio 2 - parte teorica (in Java paint o
paintComponent).
Le callback sono quelle che modificano le variabili di stato in seguito alle azioni dell'utente. NON devono contenere istruzioni grafiche, ma dopo aver modificato lo stato devono chiamare la funzione di disegno (in Java con repaint) per visualizzare il nuovo stato.
Esempio di descrizione in linguaggio naturale (si poteva usare uno stile piu' formale):
Per chi ha scritto in linguaggio naturale: vanno separate le istruzioni di assegnazione del colore e di disegno: le prime agiscono sullo stato corrente del sistema grafico e devono essere eseguite prima di disegnare la primitiva che si vuole abbia quel colore. Non va bene scrivere: "disegna il segmento... in nero".
Nota: alcuni hanno assunto che la funzione di ridisegno non inizi
pulendo l'area, ma solo aggiunga nuove parti (nuovi segmenti o
l'area piena del poligono) a quelle
disegnate la volta precedente (e la pulizia sia fatto solo quando si
svuota il poligono).
Questa NON e' un'assunzione legittima perche' la funzione di ridisegno
tipicamnente viene chiamata in situazioni (finestra appena deiconifica,
scoperta o redimensionata) in cui il disegno della volta precedente
non e' disponibile o non e' piu' valido.
Queste sono le situazioni "normali" in cui si effettua il ridisegno.
Il fatto che si ridisegni anche dopo alcune azioni utente avvenute
nell'interfaccia e' una caratteristica di questa particolare applicazione.
Sono necessarie tre callback:
La callback associata al pannello di disegno ha come input le coordinate del punto cliccato dal mouse (le arrivano tramite l'evento), e compie le seguenti operazioni:
La callback associata al bottone compie le seguenti operazioni:
La callback associata allo slider compie le seguenti operazioni:
Nota: abbiamo gestito solo abilitazione/disabilitazione del bottone (che si assume disabilitato all'inizio). Invece abbiamo lasciato lo slider abilitato sempre: vorra' dire che le modifiche alla saturazione, comunque eseguite, si vedranno solo quando il poligono sara' chiuso. Si poteva anche scegliere di disabilitare lo slider quando il poligono non e' chiuso.