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);
}
}
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.,Note that this won't help you with your NPE but will help with other errors.