Visto che abbiamo imparato a disegnare da programma perché non permettere all'utente di farlo usando il mouse?
È possibile intercettare molte azioni che l'utente esegue su un oggetto oltre la pressione di un pulsante: qui faremo esempi con il mouse ma si possono intercettare anche altre azioni. Si fa in maniera molto simile a come si fa per gestire la pressione di un pulsante soltanto che in questo caso ci serve sapere qualche informazione sull'evento: di un pulsante ci interessava soltanto il fatto che qualcuno lo avesse premuto, se un utente fa click su un punto della tela vogliamo sapere anche su quale punto ha fatto click.
Non è complicatissimo, basta collegare un frammento di programma all'evento "mouse cliccato" e in quella occasione leggere le coordinate in cui si trova il puntatore del mouse e disegnare un piccolo quadrato li sotto.
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.input.MouseEvent; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; import javafx.stage.Stage; public class Pittore extends Application{ GraphicsContext gc; @Override public void start(Stage primaryStage) { GridPane root = new GridPane(); Canvas canvas = new Canvas(300, 300); gc = canvas.getGraphicsContext2D(); canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> gestisciClick(e)); root.add(canvas, 0, 0); Scene scene = new Scene(root); primaryStage.setTitle("Picasso"); primaryStage.setScene(scene); primaryStage.show(); } public void gestisciClick(MouseEvent evento){ double posizioneX = evento.getX(); double posizioneY = evento.getY(); gc.setFill(Color.RED); // disegno un piccolo quadrato intorno al punto in cui // è stato fatto click gc.fillRect(posizioneX - 2, posizioneY - 2, 5, 5); } public static void main(String[] args) { launch(args); } }
La parte evidenziata è diversa da quella solita che usiamo con i pulsanti:
- il metodo inizia con "add" e non con "set" per enfatizzare il fatto che in questo caso possiamo mettere più
gestori degli eventi, usando
setOnAction
ne potevamo mettere soltanto uno - specifichiamo esplicitamente di quale evento vogliamo occuparci:
MouseEvent.MOUSE_CLICKED
cioè il click del mouse - il metodo che chiamiamo (quello dopo
->
) adesso ha un parametro tra le parentesi (il parametro conterrà delle informazioni che poi il gestore userà per fare il suo lavoro, ad esempio per sapere il punto in cui è stato fatto click) mentresetOnAction
non ne aveva.
Ulteriori eventi
Non siamo limitati alla gestione del singolo click (premo e rilascio il pulsante) ma anche il semplice movimento o il trascinamento del mouse.
Per fare un esperimento scriviamo un programma (prendendo spunto da quello qui sopra) seguendo
le indicazioni di seguito: il programma deve
avere un Canvas chiamato tela
a cui collegheremo 3 gestori di eventi:
tela.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> gestisciClick(e)); tela.addEventHandler(MouseEvent.MOUSE_MOVED, e -> gestisciMovimento(e)); tela.addEventHandler(MouseEvent.MOUSE_DRAGGED, e -> gestisciTrascinamento(e));
Al click del mouse il programma deve disegnare un cerchio blu di diametro 9 pixel.
Il metodo che gestisce il movimento del mouse disegna un quadratino giallo sotto al puntatore:
public void gestisciMovimento(MouseEvent e) { gc.setFill(Color.YELLOW); gc.fillRect(e.getX() - 2, e.getY() - 2, 5, 5); }
gestisciTrascinamento(e)
fa esattamente la stessa cosa soltanto che
il quadratino è di colore verde.
Una volta completato il programma provandolo sarà possibile vedere le differenze tra i diversi eventi.