Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352

    [Pillola]Eventi ed ascoltatori personalizzati in Java secondo il modello Swing

    Per seguire il funzionamento degli eventi in java bisogna definire un evento personalizzato, estendendo la classe EventObject. Esempio:

    Codice PHP:
    class MyEvent extends EventObject{

        public 
    MyEvent(Object source){
            
    super(source);
        }

        
    //piu eventuali altri metodi pubblici...


    Quindi si definisce un'interfaccia che estende EventListener e che definisce quali metodi devono essere implementati da un ascoltatore di tale evento:

    Codice PHP:
    interface MyEventListener extends EventListener{

        
    //Metodi da implementare per essere un ascoltatore di MyStatusEvent
        
    public void myStatusChangedEvent(MyEvent e);

        
    //eventuali altri metodi


    Per mettersi in ascolto di un evento bisogna registrarsi come un ascoltatore sull'oggetto che può sollevare l'evento: la classe che solleva gli eventi deve quindi offrire dei metodi per registrare e deregistrare un listener:

    Codice PHP:
    public void addMyEventListener(MyEventListener l); 
    e

    Codice PHP:
    public void removeMyEventListener(MyEventListener l); 
    I listener possono essere raccogliere in una EventListenerList; ogni volta che bisogna generare l'evento, si crea un MyEvent evt, passandogli ad esempio come argomento il riferimento this (cioè l'oggetto che sta sollevando l'oggetto), e per ogni listener registrato, si invoca il metodo myStatusChanchedEvent(evt).

    In particolare, visto che possono essere sollevati eventi in piu punti del codice è utile implementare un metodo

    private fireMyStatusChangedEvent(....)

    che si occupa di invocare myStatusChangedEvent(evt) per ogni listener presente nella lista dei listeners.

    Ovviamente nella classe MyEvent possono essere definiti altri metodi pubblici per ricavare informazioni sull'evento, come ad esempio metodi che forniscono il valore del nuovo stato dell'oggetto. Dato che MyEvent estende EventObject, su un MyEvent evt può essere invocato il metodo

    Object getSource();

    per avere l'oggetto che ha lanciato l'evento, e che è stato passato al costruttore di MyEvent al momento della costruzione dell'evento.


    Esempio

    Data una classe che rappresenta il modello di una persona con nome e anno di nascita e vogliamo implementare il modello di eventi ed ascoltatori per ricevere le notifiche delle modifiche del nome e dell'anno.

    Codice PHP:
    import java.util.EventListener;
    import java.util.EventObject;
    import javax.swing.event.EventListenerList;



    class 
    PersonEvent extends EventObject{
        
    Person person;
        
    Object oldValue;
        
    Object newValue;
        
        public 
    PersonEvent(Person sourceObject oldValueObject newValue){
            
    super(source);
            
    this.person source;
            
    this.oldValue oldValue;
            
    this.newValue newValue;
        }
        
        public 
    Person getPerson(){
            return 
    person;
        }
        
        public 
    Object getNewValue(){
            return 
    newValue;
        }
        
        public 
    Object getOldValue(){
            return 
    oldValue;
        }    
    }


    interface 
    PersonListener extends EventListener{

        public 
    void nameChanged(PersonEvent event);
        
        public 
    void yearChanged(PersonEvent event);
        
    }


    public class 
    Person{
        private 
    String name;
        private 
    int yearOfBirth;
        private 
    EventListenerList listeners;
        
        public 
    Person(String nameint yearOfBirth){
            
    this.name name;
            
    this.yearOfBirth yearOfBirth;
            
    listeners = new EventListenerList();
        }
        
        public 
    String getName(){
            return 
    name;
        }
        
        public 
    void setName(String newName){
            if(
    name.equals(newName))
                return;
            
    String oldName this.name;
            
    name newName;
            
    fireNameChangedEvent(oldNamenewName);
        }
        
        private 
    void fireNameChangedEvent(String oldNameString newName){
            
    PersonEvent event = new PersonEvent(thisoldNamenewName);
             
    Object[] listenersArray listeners.getListenerList();
             for(
    int i listenersArray.length 2>= 0-= 2){
                 if(
    listenersArray[i] == PersonListener.class){
                     ((
    PersonListener)listenersArray[i+1]).nameChanged(event);
                 }
             }
        }
        
        public 
    int getYearOfBirth(){
            return 
    yearOfBirth;
        }
        
        public 
    void setYearOfBirth(int newYearOfBirth){
            if(
    newYearOfBirth == yearOfBirth)
                return;
            
    int oldYearOfBirth yearOfBirth;
            
    yearOfBirth newYearOfBirth;
            
    fireYearChangedEvent(oldYearOfBirthnewYearOfBirth);
        }
        
        private 
    void fireYearChangedEvent(int oldYearint newYear){
            
    PersonEvent event = new PersonEvent(this,
                new 
    Integer(oldYear), new Integer(newYear));
             
    Object[] listenersArray listeners.getListenerList();
             for(
    int i listenersArray.length 2>= 0-= 2){
                 if(
    listenersArray[i] == PersonListener.class){
                     ((
    PersonListener)listenersArray[i+1]).yearChanged(event);
                 }
             }
        }
        
        public 
    void addPersonListener(PersonListener listener){
            
    listeners.add(PersonListener.class, listener);
        }

        public 
    void removePersonListener(PersonListener listener){
            
    listeners.remove(PersonListener.class, listener);
        }

    }


    class 
    SimplePersonListener implements PersonListener{
        
        public 
    void nameChanged(PersonEvent event){
            
    System.out.println("Ricevuto evento di modifica del nome:");
            
    System.out.println("\tvecchio valore: " event.getOldValue());
            
    System.out.println("\tnuovo valore: " event.getNewValue());
            
    System.out.println();
        }
        
        public 
    void yearChanged(PersonEvent event){
            
    System.out.println("Ricevuto evento di modifica del'annod i nascita:");
            
    System.out.println("\tvecchio valore: " event.getOldValue());
            
    System.out.println("\tnuovo valore: " event.getNewValue());
            
    System.out.println();    
        }
    }

    class 
    ListenersMain{
        
        public static 
    void main(String[] args){
            
    Person p = new Person("Marco"1980);
            
    PersonListener listener = new SimplePersonListener();
            
    p.addPersonListener(listener);
            
    p.setName("Adrea");
            
    p.setYearOfBirth(1985);
            
    //non produce evento
            
    p.setYearOfBirth(1985);
        }

    Output stampato dall'esempio:

    Codice PHP:
    Ricevuto evento di modifica del nome:
        
    vecchio valoreMarco
        nuovo valore
    Adrea

    Ricevuto evento di modifica del
    'annod i nascita:
        vecchio valore: 1980
        nuovo valore: 1985 

    Notiamo che la classe Person non ha alcun riferimento diretto ai suoi listener, e ignora quali siano le classi a cui essi appartengono. Ciò permette anche di collegare lo stesso oggetto Person a più listeners contemporaneamente in maniera del tutto trasparente all'oggetto Person, ovvero lo stesso oggetto può fare da modello contemporaneamente per più componenti grafici che restano cosi tutti sincronizzati. Ad esempio, in una interfaccia grafica potremmo registrare come listener di un oggetto Person un campo di testo e una JSlider che permettono entrambe di editare l'anno di nascita: le modifiche sull'uno si ripercuoteranno automaticamente sull'altra e viceversa.

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  2. #2
    Utente di HTML.it
    Registrato dal
    Apr 2004
    Messaggi
    220
    ciao scusa ma non capisco una cosa: la classe Person è la stessa che sia genera che ascolta l'evento giusto? ma se io volessi fare in modo che una classe generi e un'altra ascolti?
    tipo un JButton con il suo ActionListener: il JButton ascolta ma colui che genera è...l'utente!! va beh non è una classe ma tanto per capirsi..

  3. #3
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Originariamente inviato da stirkland
    ciao scusa ma non capisco una cosa: la classe Person è la stessa che sia genera che ascolta l'evento giusto? ma se io volessi fare in modo che una classe generi e un'altra ascolti?
    Ma...infatti c'è la classe Person che genera l'evento e la classe SimplePersonListener che implementa PersonListener e che si mette in ascolto di un oggetto Person...

    Originariamente inviato da stirkland
    tipo un JButton con il suo ActionListener: il JButton ascolta ma colui che genera è...l'utente!! va beh non è una classe ma tanto per capirsi..
    Nel caso del JButton a generare l'evento è il JButton (difatti getSource() invocato su un ActionEvent restituisce il JButton) e a ricevere l'evento sono gli ActionListener registrati sul pulsante

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  4. #4
    Utente di HTML.it
    Registrato dal
    Apr 2004
    Messaggi
    220
    no aspetta..mi sono spiegato male...quello che volevo dire è che la classe Person che genera l'evento è anche quella che ascolta mediante i metodi addxxxListener e removexxxListener!! non capisco!!!
    io vorrei fare una cosa così: ad esempio una classe Professore che genera l'evento (nello specifico "parlare") e una classe Studente che ascolta mediante il metodo addProfListener!! cioè è un'altra classe (Studente) che ascolta e non la stessa classe Professore!!
    Professore deve implementare il metodo firexxx per generare l'evento e Studente deve implementarte addProfessoreListener.
    come posso fare?

  5. #5
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Il metodo addXXXListener deve essere implementato non da chi vuole ricevere gli eventi, ma da chi li produce, ovvero nel tuo esempio dalla classe Professore. Vicevers Studente deve implementare l'interfacce ProfessoreListener che deve avere uno o più metodi che saranno richiamati da professore sugli ascoltatori registrati quando vuole produrre l'evento

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  6. #6
    Utente di HTML.it
    Registrato dal
    Apr 2004
    Messaggi
    220
    oddio scusami...ma mi è sempre meno chiaro..ti faccio un esempio:
    una volta create le classe Professore e Studente:

    codice:
    public class Main{
      Professore prof;
      Studente st;
    
      public Main(){
        prof=new Professore();
        st=new Studente();
        st.addProfessoreLIstener(new ProfessoreListener());
      }
    
      public static void main(String[] args){
        //questi 2 metodi generano eventi
        prof.parla();
        prof.mettiUn2AiRompiballe();
    
        //e così st si comporterà di conseguenza...
      }
    }

  7. #7
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    no...è al professore che vanno aggiunti gli ascoltatori:

    prof.addProfessoreListener(st);

    Studente deve implementare l'interfaccia ProfessoreListener

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    23,890
    "BUMP!"
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Altri link...

  9. #9
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Originariamente inviato da alka
    "BUMP!"
    ?

    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.