0

我是 Java 新手,所以请帮忙 :) 我有一个名为MainFrame的超类 ,它带有 main 方法和构造函数类Run()我从名为MenuBar的子类获得 JFrame 的菜单栏。菜单栏有多个实现 ActionListener 的子类。每当我尝试使用 ActionListener 调用MainFrame超类中的方法时,我都会收到错误消息,该方法从JPanel中删除所有元素,这些元素在MainFrame构造函数方法Run()中初始化MainFrame 代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Arrays;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;


public class MainFrame {
    JFrame mainFrame;
    JPanel mainPanel;
    JPanel[] pagePanels, tablePanels;
    JScrollPane scrollBar;

    private double zoom=1;
    private int width;
    private int height;
    private GridBagConstraints c;

    //private Page blankPage = new Page();
    MenuBar menubar;
    Page blankPage;

    public static void main(String[] args) {
        MainFrame generator = new MainFrame();
        generator.Run();
    }

    public void Run() {

        pagePanels = new JPanel[100];
        tablePanels = new JPanel[100];

        menubar = new MenuBar();
        blankPage = new Page();
        c = new GridBagConstraints();

        mainFrame = new JFrame("Code Generator v.1.0");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        c.gridx=0;
        c.insets = new Insets(20,0,20,0);
        //get size of screen
        GetScreenSize();

        mainPanel=new JPanel(new GridBagLayout());

        scrollBar=new JScrollPane(mainPanel);
        scrollBar.setPreferredSize(new Dimension(width,height));

        //create main frame with height and width equal to screen size (fullscreen)
        mainFrame.setJMenuBar(menubar.getMenuBar());
        mainFrame.getContentPane().add(scrollBar);
        mainFrame.setSize(width,height);
        mainFrame.setVisible(true);
    }

    public void GetScreenSize(){
        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        width = gd.getDisplayMode().getWidth();
        height = gd.getDisplayMode().getHeight();
    }

    public void RemoveAllfromMainPanel(){
        mainPanel.removeAll();
    }


}

子类MenuBar的代码是:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class MenuBar  extends MainFrame{

    public JMenuBar getMenuBar(){

        JMenuBar menubar = new JMenuBar();

        //add menus to menu bar 
        JMenu file = new JMenu("File");
        menubar.add(file);

        //add items to File menu
        JMenuItem newReport = new JMenuItem("New report");
        file.add(newReport);
        newReport.addActionListener(new newReport());

        JMenuItem exit = new JMenuItem("Exit");
        file.add(exit);
        exit.addActionListener(new exitAction());

        return menubar;

    }

    class exitAction implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            System.exit(0);
        }
    }
    class newReport implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            RemoveAllfromMainPanel();
        }
    }
}

我认为它必须与继承有关,但这是我最近开始研究的主题。您能否向我解释一下为什么会出现此错误:

MainFrame.TEST 处的线程“AWT-EventQueue-0”java.lang.NullPointerException 中的异常(MainFrame.java:125)

在这一行:

mainPanel.removeAll();

先感谢您!干杯!

4

2 回答 2

1

您实际上有两个不同的实例,这就是这里的问题。

首先,当您启动应用程序时,您创建一个MainFrame对象并调用Run该实例(请使用小写的方法名称)。该实例具有正确初始化的字段mainPanel

然后你创建一个MenuBar扩展的类的第二个实例MainFrame。它继承了超类的字段,但继承其他实例的值。所以MenuBar对象也有一个mainPanel字段,但就是null. 现在,当您调用RemoveAllfromMainPanel()menuBar 时,您可以从 menuBar 实例访问该字段并调用removeAll哪个null会导致 NPE。

于 2013-07-05T21:04:14.040 回答
1

MenuBar不应该从MainFrame. 这与您的 run 方法从您的main方法创建的实例不同,这意味着mainPanel尚未初始化。

相反,您应该在创建它时传递MenuBar一个实例的引用MainFrame

    menubar = new MenuBar(this);

在你的菜单栏上......

public class MenuBar {

    private MainFrame mainFrame;

    public MenuBar(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
    }

    /* other code */


    class newReport implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            mainFrame.RemoveAllfromMainPanel();
        }
    }
 }
于 2013-07-05T21:06:04.047 回答