【问题标题】:JPanel Issue : java.lang.NullPointerExceptionJPanel 问题:java.lang.NullPointerException
【发布时间】:2014-04-26 18:43:00
【问题描述】:

如何正确添加在“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;

    }



}

【问题讨论】:

    标签: java swing jframe jpanel panels


    【解决方案1】:

    您遇到的最大问题是不正确/不正确/不必要地使用继承。您认为仅仅因为RoomSystem 扩展了MainSystemroomPanel 将在两个类之间共享。它不是那样工作的。所以MainSystem中的roomPanel永远不会被初始化,这导致NullPointerException

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

    但你只是向你解释发生了什么。

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

    static 字段roomPanel,对于初学者来说似乎是正确的解决方法,但它完全不合适。如果您希望RoomSystem 成为它自己的面板,那么您应该将其设为extends Panel MainSystem,您只需将RoomSystem 面板添加到MainSystem 框架.

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

    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();
             }
        } 
    }
    

    【讨论】:

      【解决方案2】:

      roomPanel 为空。您需要在将其添加到 mainPanel 之前对其进行初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-28
        • 2020-10-08
        • 2014-04-30
        • 2014-06-04
        • 2016-03-06
        • 2016-07-31
        • 2011-06-29
        相关资源
        最近更新 更多