Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Eventi e listener personalizzati

    Salve a tutti...vorrei fare una cosa molto semplice...

    Creo una classe e la voglio associare ad un evento di una mia classe, un'altra classe, che ho creato...Come è possibile farlo??

    Per esempio fare che all'interno della classe con l'evento personalizzato venga fatto un emit evento(parametro) che viene preso dall'altra classe...

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Eventi e listener personalizzati

    Originariamente inviato da lizard88mc
    Creo una classe e la voglio associare ad un evento di una mia classe, un'altra classe, che ho creato...Come è possibile farlo??

    Per esempio fare che all'interno della classe con l'evento personalizzato venga fatto un emit evento(parametro) che viene preso dall'altra classe...
    Vuoi:

    a) sfruttare al minimo la OOP per "disaccoppiare" due classi attraverso l'uso di una interfaccia Xyz in modo che chi deve notificare qualcosa ha solo bisogno di avere un reference di tipo Xyz che sarà poi realmente un oggetto di un'altra classe che implementa quella interfaccia?

    oppure

    b) Implementare il design pattern "Observer"?

    oppure

    c) Definire e gestire un "listener" (è una specializzazione del pattern Observer) personalizzato in linea come inteso per la gestione degli eventi in AWT/Swing?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Io ho una classe, prendi come esempio un dado...

    Quando questo dado viene lanciato, cliccando cioè sul suo pulsante, voglio fare in modo che venga lanciato una specie di segnale, che verrà preso e gestito da un'altra classe...per esempio la classe che gestisce la partita..Ed in + in questo segnale c voglio anche passare dei parametri, in questo caso l'intero uscito dal lancio del dado...

    So che x esempio con le Qt e C++ è possibile fare una cosa simile...non riesco a fare la stessa cosa in java..

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da lizard88mc
    Quando questo dado viene lanciato, cliccando cioè sul suo pulsante, voglio fare in modo che venga lanciato una specie di segnale, che verrà preso e gestito da un'altra classe...per esempio la classe che gestisce la partita..Ed in + in questo segnale c voglio anche passare dei parametri, in questo caso l'intero uscito dal lancio del dado...
    Ma ti sono chiare le 3 possibilità che ho elencato?? Almeno a grandi linee le differenze??

    La più semplice sfruttando comunque la OOP è questa:

    codice:
    public interface RicevitoreDado {
        void dadoLanciato(int numero);
    }
    
    
    public class GestoreLancioDado {
        private RicevitoreDado rd;
    
        public GestoreLancioDado(RicevitoreDado rd) {
            this.rd = rd;
        }
    
        .....
            // quando dovrà lanciare il "segnale" a chi implementa RicevitoreDado
            rd.dadoLanciato(....);
    }
    
    
    public class GestorePartita implements RicevitoreDado {
        ....
    
        .... new GestoreLancioDado(this);
    
        public void dadoLanciato(int numero) {
             // fai quello che vuoi con il numero del dado
        }
    }
    Questo che ho appena mostrato, anche se abbozzato, non è il pattern "Observer" e non è nemmeno un "listener" (come inteso in AWT/Swing). È semplicemente un uso minimo/logico della OOP per disaccoppiare 2 classi e fare in modo che una possa invocare "qualcosa" su un altro oggetto "sapendo" solamente che implementa la interfaccia che rappresenta qualcuno che può ricevere la notifica.

    Ti è chiaro?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    si ok...questa è semplice programmazione ad oggetti direi...abbastanza normale mi pare anche di capire...quello che però io stavo cercando di capire è se è possibile create listener ed eventi come vengono gestiti all'interno delle librerie Swing e Awt...così come vengono implementati di default da queste due librerie, aggiungere eventi e listener miei personalizzati..nel vero e proprio senso di listener ed eventi..

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da lizard88mc
    se è possibile create listener ed eventi come vengono gestiti all'interno delle librerie Swing e Awt...
    Certo, ovviamente, che è possibile!

    Per gestire un listener è necessario seguire i seguenti passi:

    a) Definisci una interfaccia per il tuo listener es. XyzListener. Questa interfaccia dovrebbe estendere java.util.EventListener in linea di massima. In realtà non è strettamente necessaria questa estensione. Lo è se vuoi fare le cose in modo davvero "allineato" a quello che fa AWT/Swing e quindi vuoi usare la classe apposita per tenere la lista dei listener (vedi tra poco). Estenderla comunque non fa certo male ... anche perché è una interfaccia di "marcatura" .... non ha metodi!

    b) In questa interfaccia XyzListener definisci i metodi che descrivono le notifiche degli eventi. Dovrebbero avere tipo di ritorno 'void' e avere 1 solo parametro di tipo XyzEvent.

    c) Definisci una classe XyzEvent per modellare le informazioni sull'evento. Dovrebbe estendere come minimo java.util.EventObject che contiene solo la informazione sulla "sorgente" dell'evento. Per gli eventi AWT e alcuni di Swing c'è di mezzo un java.awt.AWTEvent ma se vuoi fare un tuo listener basta sicuramente estendere direttamente EventObject.
    Nella classe XyzEvent si possono definire N altre proprietà legate all'evento specifico e generalmente si mette il costruttore che riceve tutte queste proprietà da assegnare a campi interni e si forniscono i metodi "getter" per ottenere queste informazioni. E in linea di massima l'evento dovrebbe essere "immutabile", ovvero niente metodi "setter".

    d) Il "componente" AWT/Swing o in generale una qualunque classe che deve gestire il listener deve fornire i due metodi add/remove per aggiungere o rimuovere un listener. Qui la questione è: quale struttura dati usare per tenere la lista dei listener??
    Questo dipende da vari fattori.

    I componenti Swing che estendono JComponent ereditano (da JComponent) un campo:

    protected EventListenerList listenerList;

    dove javax.swing.event.EventListenerList è una classe apposita che permette di gestire listener, anche in modo "eterogeneo". Vuol dire che un oggetto EventListenerList può contenere contemporaneamente oggetti listener anche di diverso tipo es. AbcListener, XyzListener, javax.swing.event.CaretListener, ecc....

    Se la tua classe deriva in un modo o nell'altro da JComponent puoi quindi sfruttare questo EventListenerList, che è già istanziato, non devi fare nulla di particolare, solo usare quel campo 'listenerList'.
    Se la tua classe non estende JComponent puoi comunque usare ancora EventListenerList, basta che metti un "tuo" campo es. 'listaEventi' di tipo EventListenerList e ovviamente ne crei una istanza!

    Se si usa EventListenerList la interfaccia dell'evento deve estendere java.util.EventListener.

    I componenti AWT usano un'altra classe per la collezione dei listener che si chiama AWTEventMulticaster ma è estremamente specifica per i listener di AWT. Motivo per cui si può tranquillamente ignorare questa classe, a meno che si faccia qualcosa di strettamente legato ad AWT.

    Se non si vuole usare EventListenerList o la interfaccia non estende EventListener, si può usare una qualunque altra collezione, purché l'aggiunta/rimozione sia thread-safe. Questo è tassativo, la (de)registrazione deve poter essere fatta in modo "safe" da qualunque thread, non solo dal EDT.
    Quindi es. ArrayList o LinkedList non vanno bene. Andrebbe bene Vector (ma poi bisogna fare un po' attenzione alla iterazione) o se si usa almeno Java 5 anche meglio java.util.concurrent.CopyOnWriteArrayList che tra l'altro è adattissimo perché l'iteratore è di tipo "snapshot" (una "istantanea").

    e) Ad un certo punto nella vita del tuo componente/oggetto sarà necessario inviare un evento ai listener registrati. Questo comporta una "iterazione" (come ... dipende dal tipo della collezione) sulla lista dei listener, si ottiene ognuno dei reference ai listener e si invoca il metodo specifico dell'evento, passando il XyzEvent (sarebbe meglio lo stesso oggetto evento per tutta una singola iterazione, ecco perché è meglio se l'evento è "immutabile").

    La classe del tuo "componente" dovrebbe avere un metodo interno chiamato tipicamente fireBlaBla(.....) (dove BlaBla è il nome similare a quello dei metodi nella interfaccia) che riceve come argomenti i dati dell'evento.
    Questo metodo si occuperà di ottenere la lista dei listener, creare l'oggetto XyzEvent e invocare il metodo blaBla() su tutti i listener registrati.

    f) Opzionalmente, non strettamente necessario, si può fornire un metodo che restituisce una lista o array di tutti i listener registrati di un certo tipo. Ad esempio tramite un metodo:

    public XyzListener[] getXyzListeners()


    Note finali: la mia descrizione probabilmente non è completamente sufficiente per capire bene tutto quanto. Consiglio quindi di:

    1) Leggere la documentazione di javax.swing.event.EventListenerList (dove c'è un esempio di codice)

    2) Guardare eventualmente i sorgenti di alcune classi Swing come ad esempio:
    - javax.swing.AbstractButton (in particolare i metodi addActionListener/removeActionListener/fireActionPerformed)
    - javax.swing.AbstractListModel
    - javax.swing.Timer
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    t ringrazio veramente per la spiegazione...appena ho un attimo di calma ci do un'occhiata approfondita...

    Grazie infinite...

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 © 2025 vBulletin Solutions, Inc. All rights reserved.