JPanel Issue : java.lang.NullPointerException



如何正确添加在"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扩展了MainSystemroomPanel就会在两个类之间共享。它不是那样工作的。因此,MainSystem中的roomPanel从未初始化,这导致NullPointerException

您需要重新思考您的类设计,并且在不使用继承的情况下,因为看起来您不知道如何正确使用它,而且这是不合适的。

但只要你向你解释一下发生了什么。

您有RoomSystem,它扩展了MainSystem。所以RoomSystem自己的实体,但MainSystem具有(而不是共享)相同的属性和方法,但它们在对象引用方面绝对没有关系。因此,当您在RoomSystem中调用setRoomPanel(new JPanel());时,您只是在RoomSystem类中设置roomPanel,而不是在MainSystem类中设置。

对于初学者来说,static字段roomPanel似乎是正确的修复方法,但它完全不合适。如果你想让RoomSystem成为它自己的面板,那么你应该让它成为extends Panel而不是MainSystem,你可以把RoomSystem面板添加到MainSystem框架中。

如果您需要传递一些东西,比如从MainSystemRoomSystemCardLayout,那么您可以通过构造函数注入它。

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之前,您需要对其进行初始化。

相关内容

  • 没有找到相关文章