Créer un événement personnalisé en Java

194

Je veux faire quelque chose comme ça en Java mais je ne connais pas le chemin:

Lorsque l'événement "objet 1 dire" bonjour "" se produit, alors l'objet 2 répond à cet événement en disant "bonjour".

Quelqu'un peut-il me donner un indice ou un exemple de code?

conmadoi
la source

Réponses:

423

Vous voudrez probablement examiner le modèle d'observateur .

Voici un exemple de code pour commencer:

import java.util.*;

// An interface to be implemented by everyone interested in "Hello" events
interface HelloListener {
    void someoneSaidHello();
}

// Someone who says "Hello"
class Initiater {
    private List<HelloListener> listeners = new ArrayList<HelloListener>();

    public void addListener(HelloListener toAdd) {
        listeners.add(toAdd);
    }

    public void sayHello() {
        System.out.println("Hello!!");

        // Notify everybody that may be interested.
        for (HelloListener hl : listeners)
            hl.someoneSaidHello();
    }
}

// Someone interested in "Hello" events
class Responder implements HelloListener {
    @Override
    public void someoneSaidHello() {
        System.out.println("Hello there...");
    }
}

class Test {
    public static void main(String[] args) {
        Initiater initiater = new Initiater();
        Responder responder = new Responder();

        initiater.addListener(responder);

        initiater.sayHello();  // Prints "Hello!!!" and "Hello there..."
    }
}

Article associé: Java: création d'un événement personnalisé

aioobe
la source
Y a-t-il une raison légitime que stackoverflow.com/suggested-edits/237242 ne soit pas passée? Il montre comment faire cela avec 2 classes comme la question initialement posée.
GlassGhost
2
Que faire si plusieurs threads génèrent les événements source, est-ce que cela sera correctement synchronisé?
Mike G
8
@GlassGhost: Il a été rejeté car il s'agissait essentiellement d'une réécriture totale. Les modifications apportées à la réponse de quelqu'un d'autre sont bonnes si elles corrigent les fautes de frappe, le formatage et les liens brisés, etc., mais elles ne devraient pas changer radicalement le contenu. (Certaines exceptions s'appliquent pour les messages marqués "wiki communautaire".)
cHao
1
Java n'a-t-il aucun élément intégré pour cela? Je préférerais vraiment faire cela dans un modèle abstrait, pas implémenter la boucle for pour chaque événement.
Tomáš Zato - Réintégrer Monica le
1
Comme java.util.Observer est devenu obsolète à partir de Java 9, y aurait-il une meilleure option pour implémenter un événement personnalisé?
Udaya Shankara Gandhi Thalabat le
27

Ce que vous voulez, c'est une implémentation du modèle d'observateur . Vous pouvez le faire vous-même ou utiliser des classes Java comme java.util.Observeretjava.util.Observable

Bozho
la source
2
Réutiliser - Recycler. Mais jetez un œil à stackoverflow.com/questions/2380676/…
count0
21

Vous pouvez souhaiter configurer cela de 3 manières différentes:

  1. Thrower à l'intérieur de Catcher
  2. Catcher à l'intérieur de Thrower
  3. Throweret à l' Catcherintérieur d'une autre classe dans cet exempleTest

L'EXEMPLE DE TRAVAIL GITHUB JE CITE Par défaut, l'option 3, pour essayer les autres, décommentez simplement leOptionalbloc de code"" de la classe que vous voulez être principale, et définissez cette classe comme${Main-Class}variable dans lebuild.xmlfichier:

4 choses nécessaires pour lancer du code secondaire:

import java.util.*;//import of java.util.event

//Declaration of the event's interface type, OR import of the interface,
//OR declared somewhere else in the package
interface ThrowListener {
    public void Catch();
}
/*_____________________________________________________________*/class Thrower {
//list of catchers & corresponding function to add/remove them in the list
    List<ThrowListener> listeners = new ArrayList<ThrowListener>();
    public void addThrowListener(ThrowListener toAdd){ listeners.add(toAdd); }
    //Set of functions that Throw Events.
        public void Throw(){ for (ThrowListener hl : listeners) hl.Catch();
            System.out.println("Something thrown");
        }
////Optional: 2 things to send events to a class that is a member of the current class
. . . go to github link to see this code . . .
}

2 Éléments nécessaires dans un fichier de classe pour recevoir les événements d'une classe

/*_______________________________________________________________*/class Catcher
implements ThrowListener {//implement added to class
//Set of @Override functions that Catch Events
    @Override public void Catch() {
        System.out.println("I caught something!!");
    }
////Optional: 2 things to receive events from a class that is a member of the current class
. . . go to github link to see this code . . .
}
GlassGhost
la source
6
@GlassGhost: Le problème est que mainc'est statique, et il n'y a rien de tel qu'une thisfonction statique. Vous devez créer un new Catcher1()quelque part et transmettre cette instance à la place. 1.5 ne permettait pas non plus thisdans un contexte statique; je suis presque sûr que cela n'a jamais été autorisé.
cHao
6
@GlassGhost: le code qui utilise thisest dans un constructeur, pas dans main. Voilà pourquoi ça marche. Déplacez-le vers main, et je vous garantis que ce ne sera pas le cas. C'est ce que les gens ont essayé de vous dire et ce que votre réponse essaie de faire. Je m'en fous de ce qui est sur github - je me soucie de ce qu'il y a sur SO. Et ce que vous avez sur SO est cassé.
cHao
7
@GlassGhost: Je ne pense pas que votre réponse soit globalement inadéquate. Le problème que je vois avec cela est que le code ne fonctionnera pas tel quel - vous essayez d'utiliser à thispartir de main, qui ne compilera dans aucune version publiée de Java. Si cette partie était dans un constructeur à la place, ou si elle était maincréée new Catcher1()et utilisée à la place de this, elle devrait fonctionner, même dans 1.6+.
cHao
6
@GlassGhost: "Une méthode déclarée staticest appelée une méthode de classe. Une méthode de classe est toujours appelée sans référence à un objet particulier. Une tentative de référencer l'objet actuel à l'aide du mot clé thisou du mot clé superou de référencer les paramètres de type de tout objet environnant. une déclaration dans le corps d'une méthode de classe entraîne une erreur de compilation. " - JLS pour Java 5, §8.4.3.2
cHao
33
C'est l'un des styles de code les plus étranges que j'ai jamais vu
Eric
4

Ce qui suit n'est pas exactement le même mais similaire, je cherchais un extrait pour ajouter un appel à la méthode d'interface, mais j'ai trouvé cette question, j'ai donc décidé d'ajouter cet extrait pour ceux qui le recherchaient comme moi et ont trouvé cette question :

 public class MyClass
 {
        //... class code goes here

        public interface DataLoadFinishedListener {
            public void onDataLoadFinishedListener(int data_type);
        }

        private DataLoadFinishedListener m_lDataLoadFinished;

        public void setDataLoadFinishedListener(DataLoadFinishedListener dlf){
            this.m_lDataLoadFinished = dlf;
        }



        private void someOtherMethodOfMyClass()
        {
            m_lDataLoadFinished.onDataLoadFinishedListener(1);
        }    
    }

L'utilisation est la suivante:

myClassObj.setDataLoadFinishedListener(new MyClass.DataLoadFinishedListener() {
            @Override
            public void onDataLoadFinishedListener(int data_type) {
                }
            });
Ivan
la source