【问题标题】:Null Pointer Exception When Calling Method from another class Using an Object [duplicate]使用对象从另一个类调用方法时出现空指针异常[重复]
【发布时间】:2016-05-27 21:29:26
【问题描述】:

所以我正在为学校制作一个随机迷宫生成器。我目前正在努力为用户添加通过箭头键移动迷宫的功能。问题是,当我从事件侦听器类调用主类 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);
    }

}

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)

提前致谢!

【问题讨论】:

  • 当您遇到错误时,请务必发布行号。
  • 这是太多代码,无法查看。请将其缩减到 最少 仍能重现问题的代码量。删除所有不直接导致错误或与错误相关的代码。请参阅minimal reproducible example 了解更多信息。
  • I have looked through those posts and they all do not seem to apply to/address my problem. - 原因总是一样的:an Object is null。这是您将遇到的最常见的异常。我希望您不要期望每次获得 NPE 时都会发布问题。解决方案是查看导致问题的语句确定该行上的哪个变量为空。然后解决问题。我们不知道您的 Maze 类的第 263 行是什么。
  • 现在,当您删除 LineComponent 类时,您的示例不再完整 - 甚至比以前更糟... Minimal 并不意味着简单地省略 any 代码,但要删除不相关的代码(在您的情况下,例如,与问题完全无关的 JMenu Info/About/Creator)。

标签: java swing class object nullpointerexception


【解决方案1】:

看看你的 MyKeyListener.keyPressed 的实现:

Maze listenMaze = new Maze();

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

但是,您很可能不想在每次按下键时都创建一个新的迷宫,而是对您在主函数中创建的迷宫进行操作。因此,您将拥有一个带有 MyKeyListener 的类成员,并最好在构造函数中对其进行初始化:

class MyKeyListener
{
    private Maze listenMaze;

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

我目前看不出为什么每次按下播放键时都需要一个新的按键监听器。所以我宁愿在 Maze.setup() 中创建它:

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

【讨论】:

  • 非常感谢您花时间回答这个问题!现在这一切都变得更有意义了。我只是不知道如何对我最初创建的 Maze 对象进行操作。
猜你喜欢
  • 1970-01-01
  • 2015-10-21
  • 2022-09-27
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多