使用对象从另一个类调用方法时出现空指针异常

时间:2016-05-27 21:29:26

标签: java swing class object nullpointerexception

所以我正在为学校制作一个随机迷宫发生器。我目前正致力于为用户添加能够通过迷宫点击箭头键的功能。问题是当我从事件监听器类调用我的主类Maze中的函数时,我得到一个NPE错误。当我尝试使用comp对象时,似乎发生在moveCircle方法中。该方法是从MyKeyListener类调用的。

错误似乎来自MyKeyListener类,并且在调用Maze类中的函数moveCircle时发生。 NPE似乎与LineComponent comp对象(来自另一个类LineComponent)相关联。从我的小知识来看,似乎这可能与我的变量范围有关,但我不知道如何解决它。

我也意识到还有很多其他关于NPE的帖子,但我查看了这些帖子,但他们似乎都没有申请/解决我的问题。

主阶级迷宫:

package mazegenerator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class Maze extends JFrame{
    //Global Variables
    int dim = 0;
    int factor = 20;//Determines scalling of maze
    int borderFactor = factor;
    int radius = 16;
    int circleX = 0;
    int circleY = 0;
    Color colour = Color.red;
    Color circleColour = Color.black;
    boolean[][] north;
    boolean[][] east;
    boolean[][] south;
    boolean[][] west;
    boolean[][] visited;
    JFrame frame;
    public LineComponent comp;
    JTextArea time;
    JPanel buttonsPanel;


    public void setup(){
        ImageIcon icon = new ImageIcon("drmaze4.gif");
        frame = new JFrame("Random Maze Generator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setIconImage(icon.getImage());
        frame.setBackground(Color.LIGHT_GRAY);
        frame.setCursor(Cursor.HAND_CURSOR);

        try{
            dim = Integer.decode((String)JOptionPane.showInputDialog(frame, "Welcome to the random maze generator!\nEnter The Side Length (Integer 10 -> 45) Of The Maze:\n(Scale is input x 10 in pixels)",null,JOptionPane.INFORMATION_MESSAGE, null, null, 40));
            if(dim < 10 || dim > 45){
                dim = 40;
            }
        }catch(NumberFormatException e){
            dim = Integer.decode((String)JOptionPane.showInputDialog(frame, "Please Enter A Valid Integer!", null,JOptionPane.ERROR_MESSAGE));
            if(dim < 10 || dim > 45){
                dim = 40;
            }
        }
        comp = new LineComponent();
        comp.setPreferredSize(new Dimension(dim*borderFactor, dim*borderFactor));
        frame.getContentPane().add(comp, BorderLayout.CENTER);
        buttonsPanel = new JPanel();
        buttonsPanel.setBackground(Color.gray);
        final JButton drawMazeBtn = new JButton("Draw Maze");
        buttonsPanel.add(drawMazeBtn);
        final JButton playBtn = new JButton("Play Maze");
        buttonsPanel.add(playBtn);
        playBtn.setVisible(false);
        time = new JTextArea();
        time.setSize(200, 100);
        time.setText("Maze Generation Time: ");
        time.setEditable(false);
        buttonsPanel.add(time);
        frame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);

        //menu Bar Code
        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Info");
        menu.setMnemonic(KeyEvent.VK_A);
        menuBar.add(menu);
        JMenuItem about = new JMenuItem("About", KeyEvent.VK_T);
        menu.add(about);
        JMenuItem creator = new JMenuItem("Creator", KeyEvent.VK_T);
        menu.add(creator);
        frame.setJMenuBar(menuBar);

        frame.pack();
        frame.setVisible(true);
    }

    public void play(){
        MyKeyListener listener = new MyKeyListener();
        buttonsPanel.addKeyListener(listener);
        buttonsPanel.requestFocusInWindow();
        System.out.println("Working");
        circleX = 2*factor-2;
        circleY = 2*factor-2;
        comp.addCircle(circleX, circleY, radius, circleColour);
    }

    public void moveCircle(int direction){
        if(direction == 0){//up
            System.out.println("Up");
            circleY -= factor;
            comp.removeLastCircle();
            comp.addCircle(circleX, circleY, radius, circleColour);
        }
        if(direction == 1){//right
            System.out.println("Right");
        }
        if(direction == 2){//down
            System.out.println("Down");
            comp.removeLastCircle();
            comp.addCircle(circleX, circleY, radius, circleColour);
            //repaint();
        }
        if(direction == 3){//left
            System.out.println("Left");
        }
    }

    public static void main(String[] args) {
        Maze maze = new Maze();
        maze.setup();
        maze.init();
        maze.drawBorder();
        long startTime = System.currentTimeMillis();
        maze.create(1,1);
        maze.removeRandom();
        long finishedTime = System.currentTimeMillis();
        long duration = finishedTime - startTime;
        maze.displayTime(duration);
    }

}

Class MyKeyListener:

public class MyKeyListener implements KeyListener{
    @Override
    public void keyPressed(KeyEvent e) {
        Maze listenMaze = new Maze();
        if(e.getKeyCode() == KeyEvent.VK_UP){
            //System.out.println("Up");
            listenMaze.moveCircle(0);
        }
        if(e.getKeyCode() == KeyEvent.VK_RIGHT){
            //System.out.println("Right");
            listenMaze.moveCircle(1);
        }
        if(e.getKeyCode() == KeyEvent.VK_DOWN){
            //System.out.println("Down");
        }
        if(e.getKeyCode() == KeyEvent.VK_LEFT){
            //System.out.println("Left");
            listenMaze.moveCircle(3);
        }
        //throw new UnsupportedOperationException("Not supported yet.");
    }
}

错误讯息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at mazegenerator.Maze.moveCircle(Maze.java:263)
        at mazegenerator.MyKeyListener.keyPressed(MyKeyListener.java:18)
        at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:232)
        at java.awt.Component.processKeyEvent(Component.java:6255)
        at javax.swing.JComponent.processKeyEvent(JComponent.java:2809)
        at java.awt.Component.processEvent(Component.java:6074)
        at java.awt.Container.processEvent(Container.java:2039)
        at java.awt.Component.dispatchEventImpl(Component.java:4660)
        at java.awt.Container.dispatchEventImpl(Container.java:2097)
        at java.awt.Component.dispatchEvent(Component.java:4488)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1856)
        at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:722)
        at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1000)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:865)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:686)
        at java.awt.Component.dispatchEventImpl(Component.java:4532)
        at java.awt.Container.dispatchEventImpl(Container.java:2097)
        at java.awt.Window.dispatchEventImpl(Window.java:2489)
        at java.awt.Component.dispatchEvent(Component.java:4488)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:674)
        at java.awt.EventQueue.access$400(EventQueue.java:81)
        at java.awt.EventQueue$2.run(EventQueue.java:633)
        at java.awt.EventQueue$2.run(EventQueue.java:631)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
        at java.awt.EventQueue$3.run(EventQueue.java:647)
        at java.awt.EventQueue$3.run(EventQueue.java:645)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:644)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

提前致谢!

1 个答案:

答案 0 :(得分:0)

看看你的MyKeyListener.keyPressed:

的实现
Maze listenMaze = new Maze();

每次按下某个键时都会创建一个新的迷宫,但是你不会调用setup方法,这会初始化comp成员。所以你得到一个NullPointerException。

但是,您很可能不想在每次按下某个键时创建新的Maze,而是在您在主函数中创建的那个上运行。因此,您将拥有一个具有MyKeyListener的类成员,并最好在构造函数中初始化它:

class MyKeyListener
{
    private Maze listenMaze;

    public MyKeyListener(Maze theMaze)
    {
        this.listenMaze = theMaze;
    }
}

我目前没有看到任何理由为什么每次按下播放时都需要新的按键监听器。所以我宁愿在Maze.setup()中创建它:

// ...
buttonsPanel = new JPanel();
buttonsPanel.addKeyListener(new MyKeyListener(this));
// ...