12 votes

Dispositif d'écoute de modification des propriétés de Java

J'essaie de comprendre comment écouter un changement de propriété dans une autre classe. Voici mon code :

ClassWithProperty possède la propriété que je veux écouter :

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this); 
    private int usersOnline;

    public int getUsersOnline() {
        return usersOnline;
    }

    public ClassWithProperty() {
        usersOnline = 0;
        while (usersOnline<10) {
            changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
        }
    }

    public void addPropertyChangeListener(
        PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }
    public void removePropertyChangeListener(
        PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

C'est là que j'ai besoin de connaître le changement de propriété :

public class Main {

    private static ClassWithProperty test;

    public static void main(String[] args) {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(listen());

    }

    private static PropertyChangeListener listen() {
        System.out.println(test.getUsersOnline());
        return null;
    }

}

L'événement est déclenché uniquement la dernière fois (usersOnline=10). Je suis nouveau en Java et j'ai essayé de trouver une solution, mais en vain.

17voto

a_horse_with_no_name Points 100769

Le code :

private static PropertyChangeListener listen() {
    System.out.println(test.getUsersOnline());
    return null;
}

renvoie à null ce qui signifie "pas d'objet", ce qui à son tour signifie que test.addPropertyChangeListener(listen()) est effectivement test.addPropertyChangeListener(null) qui n'enregistrera rien.

Vous devez passer une instance valide d'un PropertyChangeListener à la addPropertyChangeListener() méthode.

Modifier

Je vous suggère de lire le chapitre du tutoriel Java consacré aux PropertyChangeListeners :
http://download.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

Un autre problème de votre code est que vous appelez firePropertyChange() dans le constructeur de ClassWithProperty . Mais à ce moment-là, aucun auditeur ne peut être enregistré, et cela n'a donc aucun effet. Tout appel à addPropertyChangeListener() se produit après vous avez déclenché les événements.

Voici votre code modifié de sorte qu'il devrait fonctionner (je ne l'ai pas testé cependant...) :

public class ClassWithProperty {
    private PropertyChangeSupport changes = new PropertyChangeSupport(this);
    private int usersOnline = 0;

    public ClassWithProperty() {
    }

    public void setupOnlineUsers() 
    {
        while (usersOnline < 10) {
            changes.firePropertyChange("usersOnline", usersOnline, ++usersOnline);
        }
    }

    public int getUsersOnline() {
        return usersOnline;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }
}

public class MainListener implements PropertyChangeListener {
    private ClassWithProperty test;

    public MainListener() {
        test = new ClassWithProperty();
        test.addPropertyChangeListener(this);
        test.setupOnlineUsers();
    }

    public void propertyChange(PropertyChangeEvent evt) {
        System.out.println(test.getUsersOnline());
    }

    public static void main(String[] args) {
        new MainListener(); // do everything in the constructor
    }
}

3voto

Johnny Points 11

Ce que je fais, c'est mettre une méthode dans la classe ClassWithProperty :

public PropertyChangeSupport getPropertyChangeSupport() {
    return changes;
}

Ensuite, enregistrez les événements de changement de propriété dans le constructeur de votre classe Main() :

private void initializeListeners() {
    test.getPropertyChangeSupport().addPropertyChangeListener((PropertyChangeEvent event) -> {
        if (event.getPropertyName().equals("usersOnline"))   {
            String passedEventData = (String) event.getNewData(); 
        }
    });
}

Ainsi, vous ne répétez pas le code de votre ClassWithProperty avec des méthodes qui se trouvent déjà dans la classe PropertyChangeSupport.

lorsque vous devez déclencher un événement dans votre classe ClassWithProperty, faites-le :

changes.firePropertyChange("usersOnline", oldValue, newValue);

L'une des caractéristiques notables de cette méthode est que, si les
event.getOldValue() et event.getNewValue() sont égales, l'événement ne sera pas déclenché. Si vous souhaitez déclencher des événements répétés avec les mêmes informations, utilisez null dans le champ oldValue ; La méthode firePropertyChange() ne passe que des int, boolean et Object. Donc, si vous ne passez pas un int ou un boolean, vous devez convertir la valeur qui a été passée dans l'événement à la fin de réception.

0voto

Votre méthode ici :

public ClassWithProperty() {
    usersOnline = 0;
    while (usersOnline<10) {
        changes.firePropertyChange("usersOnline", usersOnline, usersOnline++);
        usersOnline++;
    }
}

a une boucle while qui va boucler et bloquer le fil en permanence. Ma connaissance limitée des écouteurs de changement de propriété est qu'ils écoutent les changements d'une propriété liée, ici la propriété usersOnLine ce qui signifie que la modification de la propriété ne doit être déclenchée que si ce nombre change (probablement à l'intérieur d'une quelconque setUserOnLine , addUserOnLine , removeUserOnLine et autres méthodes similaires). Pour en savoir plus sur les propriétés liées, veuillez consulter cette page : Propriétés liées

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X