如何正确添加在"RoomSystem.Java"代码中定义的JPanel?
错误:
Exception in thread "main" java.lang.NullPointerException
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at hotelManagement.MainSystem.<init>(MainSystem.java:68)
at hotelManagement.MainSystem.main(MainSystem.java:129)
第68行:getMainPanel().add(roomPanel, "Rooms");
完整代码:
MainSystem.Java:
package hotelManagement;
import java.awt.CardLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainSystem extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private JFrame mainFrame;
private JPanel mainPanel;
private static JPanel roomPanel;
private JPanel btnPanel;
private JButton btnRoom;
private JButton btnCustomer;
private JButton btnOrder;
private JButton btnSearch;
private CardLayout cLayout;
private JLabel lblUpdate;
public MainSystem(){
mainFrame = new JFrame("Hotel Management System");
mainFrame.setSize(500,300);
mainFrame.setLayout(new GridLayout(2,0));
btnRoom = new JButton("Room Editor");
btnRoom.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
getCLayout().show(getMainPanel(), "Orders");
System.out.println("You clicked Rooms");
}
});
btnCustomer = new JButton("Customer Editor");
btnOrder = new JButton("Order");
btnSearch = new JButton("Search");
lblUpdate = new JLabel("Instructions/details will go here.");
btnPanel = new JPanel();
btnPanel.add(btnRoom);
btnPanel.add(btnCustomer);
btnPanel.add(btnOrder);
btnPanel.add(btnSearch);
btnPanel.add(lblUpdate);
setMainPanel(new JPanel());
setCLayout(new CardLayout());
getMainPanel().setLayout(getCLayout());
getMainPanel().add(btnPanel, "Buttons");
getMainPanel().add(roomPanel, "Rooms");
mainFrame.add(getMainPanel());
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public JFrame getMainFrame(){
return mainFrame;
}
public void setMainFrame(JFrame mainFrame){
this.mainFrame = mainFrame;
}
public CardLayout getCLayout(){
return cLayout;
}
public void setCLayout(CardLayout cLayout){
this.cLayout = cLayout;
}
public JPanel getMainPanel(){
return mainPanel;
}
public void setMainPanel(JPanel mainPanel){
this.mainPanel = mainPanel;
}
public JPanel getBtnPanel(){
return btnPanel;
}
public void setBtnRoom(JPanel btnPanel){
this.btnPanel = btnPanel;
}
public JPanel getRoomPanel() {
return roomPanel;
}
public static void setRoomPanel(JPanel roomPanel) {
MainSystem.roomPanel = roomPanel;
}
public static void main(String[] args) {
new MainSystem();
}
}
RoomSystem.Java
package hotelManagement;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
public class RoomSystem extends MainSystem {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton btnEdit;
private JButton btnBack;
private JComboBox<String> roomType;
String[] roomArray = { "Penthouse", "Large Room", "Small Room" };
public RoomSystem() {
setRoomType(new JComboBox<>(roomArray));
btnEdit = new JButton("Create");
btnEdit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked Create");
}
});
btnBack = new JButton("Return");
btnBack.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("You clicked Back");
}
});
Label lblRoom= new Label("Room Type: ");
setRoomPanel(new JPanel());
getRoomPanel().setLayout(new GridBagLayout());
GridBagConstraints gridConst = new GridBagConstraints();
gridConst.gridx = 0;
gridConst.gridy = 0;
getRoomPanel().add(lblRoom, gridConst);
gridConst.gridx = 1;
gridConst.gridy = 0;
getRoomPanel().add(getRoomType(), gridConst);
gridConst.gridx = 0;
gridConst.gridy = 2;
getRoomPanel().add(btnEdit, gridConst);
gridConst.gridx = 1;
gridConst.gridy = 2;
getRoomPanel().add(btnBack, gridConst);
}
public JComboBox<String> getRoomType(){
return roomType;
}
public void setRoomType(JComboBox<String> roomType){
this.roomType = roomType;
}
}
最大的问题是不恰当/不正确/不必要地使用继承。您认为,仅仅因为RoomSystem
扩展了MainSystem
,roomPanel
就会在两个类之间共享。它不是那样工作的。因此,MainSystem
中的roomPanel
从未初始化,这导致NullPointerException
您需要重新思考您的类设计,并且在不使用继承的情况下,因为看起来您不知道如何正确使用它,而且这是不合适的。
但只要你向你解释一下发生了什么。
您有RoomSystem
,它扩展了MainSystem
。所以RoomSystem
是自己的实体,但在MainSystem
具有(而不是共享)相同的属性和方法,但它们在对象引用方面绝对没有关系。因此,当您在RoomSystem
中调用setRoomPanel(new JPanel());
时,您只是在RoomSystem
类中设置roomPanel
,而不是在MainSystem
类中设置。
对于初学者来说,static
字段roomPanel
似乎是正确的修复方法,但它完全不合适。如果你想让RoomSystem
成为它自己的面板,那么你应该让它成为extends Panel
,而不是MainSystem
,你可以把RoomSystem
面板添加到MainSystem
框架中。
如果您需要传递一些东西,比如从MainSystem
到RoomSystem
的CardLayout
,那么您可以通过构造函数注入它。
public class RoomSystem extends JPanel {
private CardLayout;
public RoomSystem(CardLayout layout) {
this.layout = layout;
}
}
然后,您可以在RoomSystem
类中使用MainSystem
的布局,因为它们现在引用了相同的对象。
另一个设计选项是使用设置卡的方法(在MainSystem
类中)实现一个接口。
public interface CardViewChanger {
public void setCard(String card);
public void previousCard();
}
public class MainSystem extends JFrame implements CardViewChanger {
RoomSystem roomPanel = new RoomSystem(this);
CardLayout layout;
@Override
public void setCard(String card) {
layout.show(this, card);
}
@Override
public void previousCard() {
layout.next();
}
}
public class RoomSystem extends JPanel {
CardViewChanger cardChanger;
public RoomSystem(CardViewChanger cardChanger) {
this.cardChanger = cardChanger;
...
public void actionPerformed(ActionEvent e) {
cardChanger.previousCard();
}
}
}
roomPanel为null。在将其添加到mainPanel之前,您需要对其进行初始化。