2016-05-27 50 views
-1

所以我正在爲學校製作一個隨機迷宮生成器。我目前正在努力增加用戶在迷宮中移動的能力,並使用箭頭鍵。問題是,當我從事件監聽器類中調用主類Maze中的函數時,我得到一個NPE錯誤。似乎在我嘗試使用comp對象時發生在moveCircle方法中。該方法從MyKeyListener類中調用。當使用一個對象調用另一個類的方法時,空指針異常

該錯誤似乎源於MyKeyListener類,並在Maze類中的函數moveCircle被調用時發生。 NPE似乎與LineComponent對象(來自另一個類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) 

在此先感謝!

+1

當您收到錯誤時,請始終發佈行號。 –

+1

這是太多的代碼來審查。請將其修剪至仍然重現問題的**最小**數量的代碼。刪除所有不直接導致或與錯誤相關的代碼。有關更多信息,請參見[mcve]。 –

+0

'我查看了這些帖子,他們似乎都不適用於/解決我的問題。「 - 原因總是相同的:」一個對象爲空「。這是你會得到的最常見的異常。我希望你不要在每次獲得NPE時都發佈一個問題。解決方案是查看導致問題的語句確定該行上的哪個變量爲空。然後解決問題。我們不知道你迷宮課的263行是什麼。 – camickr

回答

0

看一看你的實現MyKeyListener.keyPressed的:

Maze listenMaze = new Maze(); 

您正在創建一個新的迷宮每一個鍵被按下的時候,但你不調用設置方法,這其中包括初始化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)); 
// ... 
+0

非常感謝您花時間回答這個問題!這一切現在變得更有意義。我只是不知道如何操作我最初創建的迷宮對象。 – jaybuilder

相關問題