-1

So I am making a random maze generator for school. I am currently working on adding the capability for the user to move through the maze sing the arrow keys. The problem is that when I call a function that is in my main class Maze from the event listener class I get a NPE error. Seems to occur in the moveCircle method when I try to use the comp object. That method is called from the MyKeyListener class.

The error seems to originate from the MyKeyListener class and occurs when the function moveCircle in the Maze class is called. The NPE seems to be associated with the LineComponent comp object (Which is from another class LineComponent). From my little knowledge, it seems that this probably has to do something with the scope of my variables but I don't exactly know how to solve it.

I also realize that there have been many other posts about NPE's however I have looked through those posts and they all do not seem to apply to/address my problem.

Main Class Maze:

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.");
    }
}

Error Message:

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)

Thanks In Advance!

jaybuilder
  • 23
  • 1
  • 6
  • 1
    When you're getting an error, always post the line number. – 2ARSJcdocuyVu7LfjUnB May 27 '16 at 21:31
  • 1
    This is far too much code to review. Please trim it down to the **minimal** amount of code that still reproduces the problem. Remove all of the code not directly causing or related to the error. See [mcve] for more information. – John Kugelman May 27 '16 at 21:32
  • `I have looked through those posts and they all do not seem to apply to/address my problem.` - the reason is always the same: `an Object is null`. This is the most common Exception you will get. I hope you don't expect to post a question every time you get a NPE. The solution is to look at the statement causing the problem Determine which variable on that line is null. Then fix the problem. We have no idea what line number 263 of your Maze class is. – camickr May 27 '16 at 22:02
  • Now, as you removed your LineComponent class, your example is not complete any more - even worse than before... Minimal does not mean to simply leave out *any* code, but to remove not relevant code (in your case, for example, the JMenu Info/About/Creator which is completely irrelevant for the issue). – Aconcagua May 27 '16 at 22:14

1 Answers1

0

Have a look at your implementation of MyKeyListener.keyPressed:

Maze listenMaze = new Maze();

You are creating a new Maze each time a key is pressed, but you do not call the setup method, which would initialize among others the comp member. So you get a NullPointerException.

However, you most probably do not want to create a new Maze each time a key is pressed, but operate on the one you created in your main function. So you would have a class member with MyKeyListener and best initialize it within the constructor:

class MyKeyListener
{
    private Maze listenMaze;

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

I currently do not see any reason why you needed a new key listener each time you press play. So I would rather create it within Maze.setup():

// ...
buttonsPanel = new JPanel();
buttonsPanel.addKeyListener(new MyKeyListener(this));
// ...
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • Thank you very much for taking the time to answer this! This all makes a lot more sense now. I just didn't know how to operate on the Maze object I created initially. – jaybuilder May 27 '16 at 22:41