NullPointerException для созданной кнопки в слушателе действий
Следующий код представляет собой фрагмент программы, из которой я получаю исключение nullpointer. Когда я нажимаю кнопку "Добавить" в графическом интерфейсе, появляется сообщение об ошибке, указывающее на эту строку:
buttonPanel.addButton.setEnabled(false);
отображается. Я предполагаю, что addButton является нулевым по некоторым причинам, хотя я создал его в конструкторе buttonPanel:
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 ответа
Ваша кнопочная панель требует ссылки на 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
, что делает для менее обслуживаемого кода.
Вы добавляете new AddButtonListener(parent);
перед ButtonPanel(ParentFrame parent)
полностью инициализирован, поэтому все его компоненты имеют значение null.
Вы могли бы удалить код инициализации, который:
public yourClass()
{
initComponents();
btn(false);
}
Сделайте следующее в AddButtonListener
public void actionPerformed(ActionEvent ae) {
// change all references to buttonPanel to myFrame.buttonPanel
myFrame.buttonPanel.buttonStatus = "add";
...
}
Это потому, что когда вы создаете ButtonPanel, переменная buttonPanel внутри ParentFrame, которую вы передаете, является нулевой в тот самый момент.
увидеть
public ParentFrame(){
...
// when you initialize this, buttonPanel is null until constructing is complete
buttonPanel = new ButtonPanel(this);
...
}
Поэтому AddButtonListener.buttonPanel имеет значение null.