1

以下代码是我从中获取空指针异常的程序片段。当我按下 GUI 上的“添加”按钮时,一条指向此行的错误消息:

  buttonPanel.addButton.setEnabled(false);

被展示。尽管我在 buttonPanel 的构造函数中对其进行了实例化,但我猜测 addButton 出于某种原因为空:

 addButton = new JButton("Add");
 addButton.addActionListener(buttonListener);

为什么会出现空指针错误

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at AddButtonListener.actionPerformed(AddButtonListener.java:21)

出现?当侦听器在 buttonPanel 类中编码时,程序运行良好,没有错误。在此先感谢您的帮助!

import java.awt.GridLayout;
import javax.swing.*;

public class ButtonPanel extends JPanel{
    public JButton addButton,
                   editButton,
                   deleteButton,
                   acceptButton,
                   cancelButton,
                   exitButton;

    public JPanel topPanel,
                   exitPanel;

    private ParentFrame parentFrame;

    public static String buttonStatus;

    public ButtonPanel(ParentFrame parent){
        parentFrame = parent;

        buttonStatus = "idle";
        //Create Buttons

        AddButtonListener buttonListener = new AddButtonListener(parent);
        addButton = new JButton("Add");
        addButton.addActionListener(buttonListener);
        editButton = new JButton("Edit");
        deleteButton = new JButton("Delete");
        acceptButton = new JButton("Accept");
        cancelButton = new JButton("Cancel");
        exitButton = new JButton("Exit");

        //Manipulate Buttons
        acceptButton.setEnabled(false);
        cancelButton.setEnabled(false);

        //Add to panels
        topPanel = new JPanel();
        topPanel.add(addButton);
        topPanel.add(editButton);
        topPanel.add(deleteButton);
        topPanel.add(acceptButton);
        topPanel.add(cancelButton);

        exitPanel = new JPanel();
        exitPanel.add(exitButton);

        this.setLayout(new GridLayout(2,1));
        this.add(topPanel);
        this.add(exitPanel);
    }
}

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class AddButtonListener implements ActionListener{

    private ParentFrame myFrame;

    private ButtonPanel buttonPanel;

    public AddButtonListener(ParentFrame parent){
        myFrame = parent;
        buttonPanel = parent.buttonPanel;
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        buttonPanel.buttonStatus = "add";

        buttonPanel.addButton.setEnabled(false);
        buttonPanel.editButton.setEnabled(false);
        buttonPanel.deleteButton.setEnabled(false);

        buttonPanel.acceptButton.setEnabled(true);
        buttonPanel.cancelButton.setEnabled(true);
    }

}

import java.awt.BorderLayout;
import javax.swing.JFrame;

public class ParentFrame extends JFrame{

    public ButtonPanel buttonPanel;

    public ParentFrame(){
        this.setResizable(false);

        buttonPanel = new ButtonPanel(this);

        this.add(buttonPanel, BorderLayout.SOUTH);
        this.pack();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(400, 300);
    }

    public static void main(String[] args){
        ParentFrame frame = new ParentFrame();
        frame.setVisible(true);
    }
}
4

4 回答 4

2

您的按钮面板需要ParentFrame构造一个引用。ButtonPanel正在父框架中构建并创建一个侦听器,该侦听器引用父框架的按钮面板。

不幸的是,此时尚未分配按钮面板,因此您的动作侦听器具有分配给其按钮面板实例的空值。

我认为问题是您的按钮面板实例在您的AddButtonListener.

您可以通过将 ButtonPanel 实例传递给构造函数来解决此问题AddButtonListener。由于AddButtonListener不使用ParentFrame,所以根本不要费心传递它。

private ButtonPanel buttonPanel;
public AddButtonListener(ButtonPanel panel){
    myFrame = parent;
    buttonPanel = panel;
}

然后在您的按钮面板构造函数中:

public ButtonPanel(ParentFrame parent){
    parentFrame = parent;

    buttonStatus = "idle";
    //Create Buttons

    AddButtonListener buttonListener = new AddButtonListener(this);
    //rest the code

除此之外,你不应该构建这样的东西。您正在做的是将您的ButtonPanel与您的ParentFrame. 这意味着如果您的父框架发生更改,它可能会导致另一个更改ButtonPanel,这会导致代码的可维护性降低。

于 2013-08-12T17:49:53.663 回答
1

在 AddButtonListener 中执行以下操作

public void actionPerformed(ActionEvent ae) {
    // change all references to buttonPanel to myFrame.buttonPanel
    myFrame.buttonPanel.buttonStatus = "add";
    ...
}

这是因为当您构造 ButtonPanel 时,您传递的 ParentFrame 内的 buttonPanel 变量在那一刻为空。

public ParentFrame(){
    ...
    // when you initialize this, buttonPanel is null until constructing is complete
    buttonPanel = new ButtonPanel(this);
    ...
}

因此 AddButtonListener.buttonPanel 为空。

于 2013-08-12T17:59:37.857 回答
1

您在完全初始化new AddButtonListener(parent);之前添加,所以它的所有组件都是空的。ButtonPanel(ParentFrame parent)

于 2013-08-12T17:50:48.693 回答
1

您可能已经删除了初始化代码,即:

public yourClass()
{
    initComponents();
    btn(false);
}
于 2018-11-29T10:01:50.440 回答