Java PropertyChangeListener

The code:

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

returns null which means "no object", which in turn means that test.addPropertyChangeListener(listen()) is effectively test.addPropertyChangeListener(null), which won't register anything.

You must pass a valid instance of a PropertyChangeListener to the addPropertyChangeListener() method.

Edit

I suggest you read the Java tutorial's chapter about PropertyChangeListeners:
http://download.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html

Another problem of your code is that you call firePropertyChange() in the constructor of ClassWithProperty. But at that time, no listener can possibly be registered, so it does not have any effect. Any call to addPropertyChangeListener() happens after you have fired the events.

Here is your code modified so that it should work (haven't tested it though...):

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
    }
}

What I do is put a method in the ClassWithProperty class:

public PropertyChangeSupport getPropertyChangeSupport() {
    return changes;
}

Then, register for property change events in the constructor of your Main() class:

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

This make it so you are not repeating the code in your ClassWithProperty with methods that are already in the PropertyChangeSupport class.

when you need to fire an event in your ClassWithProperty class, do:

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

One notable feature of this method is that, if the
event.getOldValue() and the event.getNewValue() are equal, the event will not fire. If you want to fire repeated events with the same information, use null in the oldValue field; The firePropertyChange() method only passes int, boolean and Object. So if you are not passing an int or boolean, you need to cast the value that was passed in the event on the receiving end.

Tags:

Java