繁体   English   中英

JPanel问题:java.lang.NullPointerException

[英]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扩展了MainSystem ,所以roomPanel将在两个类之间共享。 它不是那样工作的。 因此roomPanel中的MainSystem永远不会初始化,这会导致NullPointerException

您需要重新考虑类设计,而无需使用继承,因为它看起来不像您知道如何正确使用它,并且不合适。

但是,您可以向您解释发生了什么。

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

对于初学者来说, static字段roomPanel似乎是正确的解决方法,但这是完全不合适的。 如果要让RoomSystem成为其自己的面板,则应使其extends Panel不是 MainSystem ,并且可以将RoomSystem面板添加到MainSystem框架中。

如果需要将诸如CardLayout这样的东西从MainSystemRoomSystem ,则可以通过构造函数将其注入。

public class RoomSystem extends JPanel {
    private CardLayout;

    public RoomSystem(CardLayout layout) {
        this.layout = layout;
    }
}

然后,您可以在RoomSystem类中使用MainSystem中的RoomSystem ,因为它们现在引用同一对象。

另一个设计选项是使用设置卡的方法(在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为空。 您需要先对其进行初始化,然后再将其添加到mainPanel中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM