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

    notificare gli eventi

    Per prima cosa auguri a tutti
    Poi vengo subito al problema, dall'esposizione fin troppo prolissa.
    Ho un problema con la gestione degli eventi che non riesco a comprendere.

    Ho una classe clsScacchieraLayout che deve notificare alcune azioni ad un'altra classe: clsScacchiera.

    Per fare questo ho proceduto come segue:
    1- ho definito una interfaccia ScacchieraListener con gli eventi da notificare:

    codice:
    package Scacchiera;
    
    import java.util.EventListener;
    
    interface ScacchieraListener extends EventListener
    {
    	public void Muovi(ScacchieraLayoutEvent event);
    	public void Invia(ScacchieraLayoutEvent event);
    	public void Indietro(ScacchieraLayoutEvent event);
    }

    2- definito una nuova classe per gli eventi:
    codice:
    package Scacchiera;
    
    import java.util.EventObject;
    
    class ScacchieraLayoutEvent extends EventObject
    {
    	private static final long serialVersionUID = 1L;
    	public String msg;
    	public String canale;
    	
    	ScacchieraLayoutEvent(clsScacchieraLayout source)
    	{
    		super(source);
    	}
    	ScacchieraLayoutEvent(clsScacchieraLayout source, String msg)
    	{
    		super(source);
    		this.msg = msg;
    	}
    	ScacchieraLayoutEvent(clsScacchieraLayout source, String msg, String canale)
    	{
    		super(source);
    		this.msg = msg;
    		this.canale=canale;
    	}
    }
    3- All'interno di clsScacchiera ho definito una nuova classe che implementa ScacchieraListener
    codice:
    class actionPerformed implements ScacchieraListener
    	{[....]}
    4- sempre da clsScacchiera viene istanziata clsscacchieralayout e fatto addlistener
    codice:
    actionPerformed handlerAction = new actionPerformed();
    		scacchieraLayout = new Scacchiera.clsScacchieraLayout(applet, bianchi, neri, tempo,socket.userName,canale);
    		scacchieraLayout.addListener(handlerAction);
    dove addListener è il metodo di ScacchieraLayout:
    codice:
    public void addListener(ScacchieraListener listener) {
    		listeners.add(ScacchieraListener.class, listener);
    	}


    5- Finalmente arrivo al problema che c'è quando faccio scattare l'evento. Se elimino le righe commentate sotto non scatta l'evento ma non riesco a capire il motivo

    codice:
    	private void fireIndietroEvent() {
    		ScacchieraLayoutEvent event = new ScacchieraLayoutEvent(this);
    		Object[] listenersArray = listeners.getListenerList();
    
    		for (int i = listenersArray.length - 1; i >= 0; i -= 2) {
    			
    			 //if(listenersArray[i] == LoginListener.class) {
    			((ScacchieraListener) listenersArray[i]).Indietro(event);
    			// }
    		}
    	}
    Qualche idea su dove sbaglio?

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Non è possibile che un istruzione (in questo caso all'interno di un ciclo) venga eseguita più volte se messa all'interno di un test che senza alcuna verifica, al massimo potrebbe essere eseguita lo stesso numero di volte, nel caso in cui la condizione si verificasse ad ogni iterazione... a meno che il metodo che tu invochi non modifichi qualcosa che sta al suo esterno, ma senza sapere cosa fa è difficile aiutarti.

    Oppure ho capito male il problema.

  3. #3
    Originariamente inviato da Kaamos
    Non è possibile che un istruzione (in questo caso all'interno di un ciclo) venga eseguita più volte se messa all'interno di un test che senza alcuna verifica, al massimo potrebbe essere eseguita lo stesso numero di volte, nel caso in cui la condizione si verificasse ad ogni iterazione... a meno che il metodo che tu invochi non modifichi qualcosa che sta al suo esterno,
    Non ho capito.

    Originariamente inviato da Kaamos
    ma senza sapere cosa fa è difficile aiutarti.

    Oppure ho capito male il problema.
    cosa fa credevo di avelo spiegato ma evidentemente mi sono espresso male.
    fireIndietroEvent fa "scattare" l'evento che viene notificato ai listeners.
    In realtà rileggendo il mio post mi sono accorto che, a causa di un copia-incolla sbagliato avevo riportato male l'istruzione commentata.
    dovrebbe essere:
    //if(listenersArray[i] == ScacchieraListener.class) {
    e non:
    //if(listenersArray[i] == LoginListener.class) {

    Di seguito il codice di fireIndietroEvent con il commento corretto e qualche linea di commento per comprendere meglio quello che fa:
    codice:
    // Questa funzione viene utilizzata per notificare ai listener l'evento "Indietro"
    	private void fireIndietroEvent() {
    		//Definisco l'evento da notificare
    		ScacchieraLayoutEvent event = new ScacchieraLayoutEvent(this);
    		//Recupero l'array dei listeners
    		Object[] listenersArray = listeners.getListenerList();
    
    		//Ciclo sull'array dei listeners
    		for (int i = listenersArray.length - 1; i >= 0; i -= 2) {
    			//Ad ogni iterazione verifico che il listener in oggetto sia di tipo ScacchieraListener.class
    			//Se il listener è del tipo atteso allora notifico l'evento "Indietro"
    			//Il problema è che l'if commentato sotto restituisce sempre false
    			//anche se il listener è di tipo ScacchieraListener
    			  //if(listenersArray[i] == ScacchieraListener.class) {
    			((ScacchieraListener) listenersArray[i]).Indietro(event);
    			// }
    		}
    	}

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da GrandFunkR
    Non ho capito.


    cosa fa credevo di avelo spiegato ma evidentemente mi sono espresso male.
    fireIndietroEvent fa "scattare" l'evento che viene notificato ai listeners.
    In realtà rileggendo il mio post mi sono accorto che, a causa di un copia-incolla sbagliato avevo riportato male l'istruzione commentata.
    dovrebbe essere:
    //if(listenersArray[i] == ScacchieraListener.class) {
    e non:
    //if(listenersArray[i] == LoginListener.class) {

    Di seguito il codice di fireIndietroEvent con il commento corretto e qualche linea di commento per comprendere meglio quello che fa:
    codice:
    // Questa funzione viene utilizzata per notificare ai listener l'evento "Indietro"
    	private void fireIndietroEvent() {
    		//Definisco l'evento da notificare
    		ScacchieraLayoutEvent event = new ScacchieraLayoutEvent(this);
    		//Recupero l'array dei listeners
    		Object[] listenersArray = listeners.getListenerList();
    
    		//Ciclo sull'array dei listeners
    		for (int i = listenersArray.length - 1; i >= 0; i -= 2) {
    			//Ad ogni iterazione verifico che il listener in oggetto sia di tipo ScacchieraListener.class
    			//Se il listener è del tipo atteso allora notifico l'evento "Indietro"
    			//Il problema è che l'if commentato sotto restituisce sempre false
    			//anche se il listener è di tipo ScacchieraListener
    			  //if(listenersArray[i] == ScacchieraListener.class) {
    			((ScacchieraListener) listenersArray[i]).Indietro(event);
    			// }
    		}
    	}
    Quando hai scritto "Se elimino le righe commentate sotto non scatta l'evento ma non riesco a capire il motivo" avevo inteso letterealmente cancellare, invece mi sa che intendevi "decommentarle", insomma eseguirle, forse non ci capivamo per questo.

    Il test è sbagliato, per vedere se un oggetto è di un certo tipo devi usare l'operatore instanceof, non ==, in questo modo:

    codice:
    if (listenersArray[i] instanceof ScacchieraListener) { ... }
    anche perché .class è un campo di tipo Class, mentre listenersArray è un array di Object che in realtà sono ognuno delle istanze di qualche listener, insomma sono proprio due oggetti diversi.

    E comunque l'operatore == con gli oggetti ha un funzionamento molto limitato: verifica che i due oggetti siano esattamente la stessa istanza della stessa classe... quindi anche con due oggetti istanziati distintamente ma esattamente uguali al loro interno, restituirebbe comunque false.

    Sempre se questa volta ho capito.

    Comunque, perché il ciclo scende di due in due?

  5. #5
    Originariamente inviato da Kaamos
    Quando hai scritto "Se elimino le righe commentate sotto non scatta l'evento ma non riesco a capire il motivo" avevo inteso letterealmente cancellare, invece mi sa che intendevi "decommentarle", insomma eseguirle, forse non ci capivamo per questo.
    Hai ragione, mi ero espresso malissimo io. Ora ci siamo capiti

    Originariamente inviato da Kaamos
    Il test è sbagliato, per vedere se un oggetto è di un certo tipo devi usare l'operatore instanceof, non ==, in questo modo:

    codice:
    if (listenersArray[i] instanceof ScacchieraListener) { ... }
    anche perché .class è un campo di tipo Class, mentre listenersArray è un array di Object che in realtà sono ognuno delle istanze di qualche listener, insomma sono proprio due oggetti diversi.

    E comunque l'operatore == con gli oggetti ha un funzionamento molto limitato: verifica che i due oggetti siano esattamente la stessa istanza della stessa classe... quindi anche con due oggetti istanziati distintamente ma esattamente uguali al loro interno, restituirebbe comunque false.

    Sempre se questa volta ho capito.

    Comunque, perché il ciclo scende di due in due?
    Il ciclo scende di due in due perchè l'array restituito da listeners.getListenerList()
    ha elementi in coppia: ScacchieraListener.class, ScacchieraListener
    listeners è una istanza di javax.swing.event.EventListenerList che viene popolata con il metodo addListener che riporto nuovamente per comodità:
    codice:
    public void addListener(ScacchieraListener listener) {
    		listeners.add(ScacchieraListener.class, listener);
    	}
    per capirci: gli elementi pari dell'array sono ScacchieraListener.class, quelli dispari sono ScacchieraListener.
    Il problema è proprio questo: il confronto dovrebbe essere:
    codice:
    if (listenersArray[i-1] == ScacchieraListener.class) { ... }
    Il concetto del confronto tra oggetti mi era chiaro, avendo una conoscenza pregressa dei concetti base di OOP, pur non avendo mai utilizzato Java prima dello sviluppo di questa applet

    Ti ringrazio per lo spunto interessante che mi ha permesso di risolvere il problema

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Kaamos
    Il test è sbagliato, per vedere se un oggetto è di un certo tipo devi usare l'operatore instanceof, non ==, in questo modo:

    Comunque, perché il ciclo scende di due in due?
    -> http://docs.oracle.com/......../event/EventListenerList.html
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Grazie ad entrambi, non l'avevo mai usato.

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.