netbeans 添加属性更改侦听器会导致java.lang.NullPointerException

afdcj2ne  于 2022-11-10  发布在  Java
关注(0)|答案(1)|浏览(104)

我是使用Netbeans和PropertyChangeListener的新手,在Java Bean中实现PropertyChangeSupport时,我遇到了同样(对我来说)的奇怪行为。
因此,我有一个名为TTTCell的bean,我在其中初始化了一个PropertyChangeSupport变量,然后实现了维护属性更改侦听器列表的函数。

package tttboard;

import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;

public class TTTCell extends javax.swing.JPanel {

    public static enum State
    {
        INITIAL,
        PLAYER_X,
        PLAYER_O,
        WON,
        DISABLE
    }

    // Variables
    private State state;
    private PropertyChangeSupport propChange = new PropertyChangeSupport(this);

    public TTTCell() {

        initComponents();
        state = State.INITIAL;
    }

    @Override
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propChange.addPropertyChangeListener(listener); // it depends on that line whether the erroroccurs or not
    }
    @Override
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propChange.removePropertyChangeListener(listener);
    }

我现在将这个bean放在另一个名为TTTBoard的bean中,它给了我以下错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

at tttboard.TTTCell.addPropertyChangeListener(TTTCell.java:55)
    at java.desktop/javax.swing.plaf.synth.SynthPanelUI.installListeners(SynthPanelUI.java:83)
    at java.desktop/javax.swing.plaf.synth.SynthPanelUI.installUI(SynthPanelUI.java:63)
    at java.desktop/javax.swing.JComponent.setUI(JComponent.java:685)
    at java.desktop/javax.swing.JPanel.setUI(JPanel.java:150)
    at java.desktop/javax.swing.JPanel.updateUI(JPanel.java:126)
    at java.desktop/javax.swing.JPanel.<init>(JPanel.java:86)
    at java.desktop/javax.swing.JPanel.<init>(JPanel.java:109)
    at java.desktop/javax.swing.JPanel.<init>(JPanel.java:117)
    at tttboard.TTTCell.<init>(TTTCell.java:38)
    at tttboard.TTTBoard.initComponents(TTTBoard.java:89)
    at tttboard.TTTBoard.<init>(TTTBoard.java:27)
    at tttboard.TTTBoard$2.run(TTTBoard.java:203)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

对我来说,这没有任何意义-PropertyChangeSupport变量是示例化的,为什么它应该是一个空指针?
仅供参考,我使用的是Netbeans IDE 11.1和openjdk 11.0.11

kyks70gy

kyks70gy1#

一个类的非静态字段直到该类进入初始化/构造时才被初始化。超类构造总是首先发生。
如果查看堆栈跟踪,可以看到异常是由于超类构造而发生的:

at java.desktop/javax.swing.JPanel.<init>(JPanel.java:117)
at tttboard.TTTCell.<init>(TTTCell.java:38)

必须先完成超类构造函数(即JPanel构造函数),然后才能运行TTTCell字段初始化与构造函数.
JPanel构造函数调用其updateUI方法,该方法最终调用addPropertyChangeListener:

at tttboard.TTTCell.addPropertyChangeListener(TTTCell.java:55)
at java.desktop/javax.swing.plaf.synth.SynthPanelUI.installListeners(SynthPanelUI.java:83)
at java.desktop/javax.swing.plaf.synth.SynthPanelUI.installUI(SynthPanelUI.java:63)
at java.desktop/javax.swing.JComponent.setUI(JComponent.java:685)
at java.desktop/javax.swing.JPanel.setUI(JPanel.java:150)
at java.desktop/javax.swing.JPanel.updateUI(JPanel.java:126)
at java.desktop/javax.swing.JPanel.<init>(JPanel.java:86)

但是TTTCell还没有机会运行它的初始化器,它不仅包括TTTCell()构造函数,还包括字段的初始化,包括下面这个:

private PropertyChangeSupport propChange = new PropertyChangeSupport(this);

由于在调用addPropertyChangeListener覆盖时该行尚未运行(因为JPanel构造函数尚未完成),因此propChange仍为空。
解决办法很简单:移除addPropertyChangeListener和removePropertyChangeListener的覆写。它们没有任何好处。Component类别已经提供了这些方法的工作实作。没有任何东西可以阻止您使用它们。

相关问题