0

我创建了一个简单的 LED,它接收来自许多数字组件(例如开关/门)中的任何一个的输入。问题是,当尝试实现 PropertyChangeListener 接口时,我得到了 NullPointerException。使用下面的代码,如果我只是将它添加到 JFrame 表单并尝试运行它,我会得到这个异常。我已经实现了与门/开关相同的 LED,但是由于某种原因,我的代码会产生错误。任何帮助表示赞赏。

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


}
4

1 回答 1

3

在 addPropertyChangeListener 上遇到 NullPointerException 的唯一方法是 PropertyChangeSupport 为空。但它显然不应该在正常创建的对象中为空,但我猜这是你的问题,你的对象没有正常创建。

由于您的对象实现了 Serializable 接口,我猜您的问题是由于您对这种类型的对象进行反序列化,但没有为反序列化对象创建瞬态 PropertyChangeSupport 对象。由于是瞬态的,反序列化时默认不创建。如果是这样,您必须更改序列化在对象中的读取方式。您将要进行自定义序列化,特别是必须覆盖该readObject(...)方法。另请查看有关序列化的有效 Java 章节


编辑
顺便说一句,您的 PropertyChangeSupport 对象应该是 SwingPropertyChangeSupport 对象,因为您的是 Swing GUI


编辑 2
但是由于您的类扩展了 JPanel,这一切都没有实际意义,因为 JPanel已经具有带有 addPropertyChangeListener 和 removePropertyChangeListener 方法的内在 PropertyChangeSupport,因此只需使用 JPanel 的内在支持。


编辑 3
哦,是的,有点小鸟告诉我你的paintComponent(...)方法覆盖有缺陷,因为你应该几乎总是在覆盖方法中调用超级方法,以便可以绘制背景并完成内务处理。IE,

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

请注意,这不会帮助您解决 NPE,但会帮助您解决其他错误。

于 2013-08-25T03:49:46.313 回答