La Gestione degli Eventi

 

 

Gli eventi sono un'aspetto importante del linguaggio che ci consente di interagire con l'applicazione. In java gli eventi sono, più che in altri linguaggi, molto performanti e possono essere lanciati non solo dai soliti oggetti grafici (bottoni, label ecc) per i soliti eventi (click, enter, exit ecc) ma anche da qualsiasi oggetto per qualsiasi tipo di accadimento.

 

 

Contenuti:

1

Mr.Webmaster - Il pattern Observer in Java

2 Unisa.it - Gestione degli eventi
3 Simplesoft.it - Gestione degli eventi in java swing
4  

 

Esempi:

1

Observer e Observable

2  
3  
4  

 

Cerchiamo di chiarirci le idee.

Esiste un oggetto che scatena l'evento (il source) ed uno che è in ascolto (il listener). Ad ogni source può essere assegnato uno o più listener ed un listener si può associare ad uno o più source, insomma si possono combinare come si vuole. In altre parole un listener non ascolta tutti ma solo l'ogetto o gli oggetti source a cui è associato. E' proprio il listener che farà qualcosa quando riceve l'evento. Facendo degli esempi se ad un bottone associo tre oggetti listener ciascuno dei quali esegue un'azione diversa per lo stesso evento, quando cliccherò il pulsante tutte e tre le azioni verranno eseguite. Ciascuno dei listener associato allo stesso oggetto potrebbe implementare un diverso evento, ad es. ad un click risponderà un listener, ad un entra un'altro, ad un esci rispondera e l'altro ancora. Se si cliccherà il pulsante solo il ilstener che ascolta per il click agirà gli altri rimarranno in attesa dell'evento per cui sono stati associati e di cui hanno sovrascritto il metodo dell'interfaccia.

Per avere degli approfondimenti andate a vedere i link 2 e 3 contenuti.

 

il Iistener è un oggetto che verrà istanziato da una classe che dovrà implementare un'interfaccia di tipo listener.

 

In modo tradizionale:

  //Tradizionale    
  class Ascolta implements ActionListener{//Crea la classe dell'ascoltatore
       @Override
       public void actionPerformed(ActionEvent evt) {//Sovrascivi il metodo dell'interfaccia
             System.out.println("Hai fatto Click in modo tradizionale"); //Fai qualcosa  
       }
  }       
  Ascolta asc = new Ascolta();//Crea un oggetto Ascoltatore       
  ButtonTrad.addActionListener(asc);//Associa l'ascoltatore al source       

 

Con una classe anonima:

  //Classe anonima
  ButtonAnon.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent evt) {
          System.out.println("Hai fatto Click con classe anonima");   
      }
  });     

 

Con espreessioni lamda:

  //Classe con espressioni lambda
  ButtonLamb.addActionListener((ActionEvent evt) -> {
      System.out.println("Hai fatto Click Espressioni Lambda");
  });

 

Discussione:

  • 13 - Creo un istanza della classe Button, un oggetto Button jButton1 che sarà il nostro source
  • 17 - 21 - Definisco la classe dell'ascoltatore che mi implementa l'interfaccia ActionListener per questo sarà costretta a riscrivere l'unico metodo di questa actionPerformed. Nel metodo andremo a fargli stampare il messaggio (questa è l'azione che verrà eseguita quando si scatenerà l'evento)
  • 22 - Rendo reale l'ascoltatore istanziando un ogetto ascoltatore
  • 23 - Associo L'ascoltatore al source

La stessa cosa si può ottenere in modo più conciso mediante l'uso di una classe anonima. Questa crea una classe di cui non sappiamo il nome che mi implementa l'interfaccia ActionListener, ne riscrive il metodo actionPerformed e mi istanzia l'oggetto ascoltatore e me lo associa al source tutto in una volta sola. Se si prende la mano si ottiene un metodo più conciso e forse più elegante del metodo tradizionale. Il risultato è lo stesso.

 

Attenzione se vi capita di avere un messaggio di errorre del genere:

 

 

Non disperate evidentemente avete copiato il codice da una pagina web e inconsapevolmente vi siete portati dietro dei caratteri che, anche se invisibili non possono essere riconosciuti dal compilatore. Basterà cancellare le linee rosse ondulate prima del codice per eliminare i caratteri indesiderati e tutto tornera al suo posto.

 

Ma java permette di fare molto di più. Immagginate di voler far scatenare un evento al cambio di una proprietà od all'esecuzione di un metodo di un oggetto, si può. Un tempo per gestire gli eventi legati al cambio di proprietà venivano usati gli Observer (il nostro Listener) e gli Observable (il Source).

La classe Observable e l’interfaccia Observer sono stati deprecati in Java 9 perché il modello di eventi supportato da Observer ed Observable è piuttosto limitato. L’ordine delle notifiche consegnate da Observable non è specificato e le modifiche di stato non sono in corrispondenza uno a uno con le notifiche. In altre parole, Observer e Observable non fornivano un modello di eventi sufficientemente ricco per le applicazioni.

Per sostituire Observer ed Observable, è consigliabile utilizzare un approccio diverso. Ecco alcune alternative:

  1. PropertyChangeListener: Questa interfaccia fornisce un meccanismo per gestire gli eventi di modifica delle proprietà. È più flessibile e offre una maggiore varietà di tipi di eventi rispetto all’approccio basato su Observer.
  2. Listeners personalizzati: Invece di utilizzare Observer, puoi creare i tuoi listener personalizzati per gestire eventi specifici. Questo ti consente di definire callback specifiche per ciascun tipo di evento.

In sintesi, Observer ed Observable sono stati deprecati a causa delle limitazioni del loro modello di eventi. Utilizza alternative più flessibili e robuste per gestire gli eventi nel tuo codice Java.

 

Per approfondimenti sull'uso di PropertyChangeListener vedi qui.

Per approfondimenti sull'uso di Listeners personalizzati vedi qui.