问题
The following code is a snippet of a program I am getting a nullpointer exception from. When I press the "Add" button on the GUI, an error message pointing to this line:
buttonPanel.addButton.setEnabled(false);
is displayed. I'm guessing that the addButton is null for some reason although I instantiated it in the constructor of buttonPanel:
addButton = new JButton("Add");
addButton.addActionListener(buttonListener);
Why is the null pointer error
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at AddButtonListener.actionPerformed(AddButtonListener.java:21)
appearing? When the listener is coded inside the buttonPanel class, the program runs fine with no errors. Thanks in advance for your help!
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);
}
}
回答1:
Your buttonpanel requires a reference to ParentFrame
to be constructed. ButtonPanel
is being constructed in parent frame and creating a listener, which references the parent frame's button panel.
Unfortunately, the button panel hasn't been assigned at that point, and so your action listener has a null value assigned to its instance of button panel.
I think the problem is your button panel instance is null in your AddButtonListener
.
You can fix this by passing a ButtonPanel instance into your AddButtonListener
constructor. As AddButtonListener
isn't using ParentFrame
, don't bother passing it at all.
private ButtonPanel buttonPanel;
public AddButtonListener(ButtonPanel panel){
myFrame = parent;
buttonPanel = panel;
}
And then in your button panel constructor:
public ButtonPanel(ParentFrame parent){
parentFrame = parent;
buttonStatus = "idle";
//Create Buttons
AddButtonListener buttonListener = new AddButtonListener(this);
//rest the code
Aside, you shouldn't be structuring things like this. What you're doing is tightly coupling your ButtonPanel
with your ParentFrame
. This means if your parent frame changes it could cause another change in ButtonPanel
, which makes for less maintanable code.
回答2:
You are adding the new AddButtonListener(parent);
before the ButtonPanel(ParentFrame parent)
is fully initialized, so all it componets are null.
回答3:
Do the following In AddButtonListener
public void actionPerformed(ActionEvent ae) {
// change all references to buttonPanel to myFrame.buttonPanel
myFrame.buttonPanel.buttonStatus = "add";
...
}
This is because while you construct the ButtonPanel, the buttonPanel variable inside ParentFrame you pass around is null at that very moment.
see
public ParentFrame(){
...
// when you initialize this, buttonPanel is null until constructing is complete
buttonPanel = new ButtonPanel(this);
...
}
Therefore AddButtonListener.buttonPanel is null.
回答4:
you might have delete the initialization code which is:
public yourClass()
{
initComponents();
btn(false);
}
来源:https://stackoverflow.com/questions/18193308/nullpointerexception-for-instantiated-button-in-action-listener