NullPointerException on addPropertyChangeListener

1.5k views Asked by At

I have created a simple LED that receives an input from any of a number of digital components such as switches/gates. The problem is that when trying to implement the PropertyChangeListener interface I get a NullPointerException. With the code below if I just add this to a JFrame form and try and run it I get this exception. I have implemented the LED the same as I did for gates/switches however for some reason my code generates an error. Any help appreciated.

package Digital;

import java.awt.Image;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;


public class LED extends javax.swing.JPanel implements PropertyChangeListener {

    private Image led_on;
    private Image led_off;
    private Image image;
    private Terminal input;
    private transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

    public LED() {
        java.net.URL url_on = getClass().getResource("images/LED_on.gif");
        led_on = new javax.swing.ImageIcon(url_on).getImage();
        this.setSize(led_on.getWidth(null), led_on.getHeight(null));
        java.net.URL url_off = getClass().getResource("images/LED_off.gif");
        led_off = new javax.swing.ImageIcon(url_off).getImage();
        this.setSize(led_off.getWidth(null), led_off.getHeight(null));
        this.image = led_off;    
    }

    @Override
    public void paintComponent(java.awt.Graphics g) {
        g.drawImage(image, 0, 0, null);
    }


    public static final String PROP_INPUT = "input";

    public Terminal getInput() {
        return input;
    }

    public void setInput(Terminal input) {
        if (input != null) {
            input.addPropertyChangeListener(this);
            this.addPropertyChangeListener(this);
        }

        Terminal oldInput = this.input;
        this.input = input;
        propertyChangeSupport.firePropertyChange(PROP_INPUT, oldInput, input);
    }



    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }


    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }



    public boolean Recalculate(Terminal input) {
        if (input!=null) {
            return input.getValue();
        } else {
            return false;
        }
    }


    public void ledChange(boolean ledValue) {
        if (ledValue) {
            image = led_on;
        } else {
            image = led_off;
        }
        repaint();
    }


    public void propertyChange(PropertyChangeEvent pce) {
        boolean terminalValue = Recalculate(input);
        ledChange(terminalValue);
    }


}
2

There are 2 answers

3
Hovercraft Full Of Eels On

The only way for you to experience a NullPointerException on addPropertyChangeListener is if PropertyChangeSupport is null. But it obviously shouldn't be null in an object created normally, but I'm guessing that this is your problem, that your objects aren't created normally.

Since your object implements the Serializable interface I'm guessing that your problem is due to your de-serializing objects of this type but not creating the transient PropertyChangeSupport object for the de-serialized object. Since it is transient, it is not created by default when de-serialized. If so, you must alter how your serialization read's in the object. You will want to do Custom Serialization and in particular will have to override the readObject(...) method. Also please check out the Effective Java chapter on Serialization.


Edit
As an aside, your PropertyChangeSupport object should be a SwingPropertyChangeSupport object since yours is a Swing GUI


Edit 2
But since your class extends JPanel, this is all moot since JPanel already has intrinsic PropertyChangeSupport complete with addPropertyChangeListener and removePropertyChangeListener methods, and so just use JPanel's intrinsic support.


Edit 3
Oh yes, a little birdy notified me that your paintComponent(...) method override is deficient as you should almost always call the super's method in the override method so that background can be drawn and housekeeping done. i.e.,

@Override
public void paintComponent(java.awt.Graphics g) {
    super.paintComponent(g); // **** add this
    g.drawImage(image, 0, 0, null);
}

Note that this won't help you with your NPE but will help with other errors.

0
Javi On

remove Nimbus look and feel as @smuzoen works for me