【问题标题】:Null Pointer Exception and Action Listeners空指针异常和动作监听器
【发布时间】:2013-02-08 09:00:37
【问题描述】:

我正在通过我的简单游戏应用程序来简化从 700 行到 177 行的所有内容,以消除重复。当我尝试运行我的应用程序时,我收到了一个Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException。我知道这意味着什么(通过阅读this),我知道这与我如何处理actionListener 有关,但我不知道确切如何

我遵循了我在处理数组和JButtons 时遇到的所有教程,但肯定有一些小问题。 private JButton[][] blocks = new JButton[rows][cols] 的声明是正确的,所以事实并非如此,我没有改变我以前版本的代码对blocks[i][j].addActionListener(this) 的处理方式,除了我用block[i][j] 更改了block1、block2 ...等。

这是扔给我的东西:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at blox.Blox.game(Blox.java:105)
    at blox.Blox.access$000(Blox.java:25)
    at blox.Blox$1.run(Blox.java:173)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:688)
    at java.awt.EventQueue$3.run(EventQueue.java:686)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

这是我的代码:

public class Blox implements ActionListener {

  private final String gameVersion = "Blox - v1.0.2";
  private final int rows = 7;
  private final int cols = 7;

  // Board Inits
  private ImageIcon purpleBlock = new ImageIcon();
  private ImageIcon redBlock = new ImageIcon();
  private ImageIcon blueBlock = new ImageIcon();
  private ImageIcon greenBlock = new ImageIcon();
  private ImageIcon closeImage = new ImageIcon();
  private JButton[][] block = new JButton[rows][cols];
  private JPanel boardBg = new JPanel();

  // Error console init
  private JLabel errorMessage = new JLabel();
  private JPanel errorBg = new JPanel();
  private JButton closeError = new JButton();

  // Score/UI Inits
  private JButton resetBoard = new JButton("Reset Board");

  /**
   *  700 x 480 Frame Size
   *  Sets Up and displays initial scene.
   *
   */
  private void game() {

    // Initialize mainFrame
    JFrame mainFrame = new JFrame(gameVersion);
    Dimension minSize = new Dimension(700,480);
    mainFrame.setMinimumSize(minSize);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.setLayout(null);
    mainFrame.setResizable(false);
    try {
      mainFrame.setContentPane(new JLabel(new ImageIcon(
          ImageIO.read(new File("bggrad.jpg")))));
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Setup block Images
    try {
      purpleBlock.setImage(ImageIO.read(new File("purpleBlock.png")));
      redBlock.setImage(ImageIO.read(new File("redBlock.png")));
      blueBlock.setImage(ImageIO.read(new File("blueBlock.png")));
      greenBlock.setImage(ImageIO.read(new File("greenBlock.png")));
      closeImage.setImage(ImageIO.read(new File("close.jpg")));
    } catch (IOException e) {
      e.printStackTrace();
    }

    // Sets up error message panel
    // Only displayed if error occurs on ActionListener
    errorMessage.setText("");
    errorMessage.setForeground(Color.black);
    Font newLabelFont = new Font(errorMessage.getFont().getName(),
        Font.BOLD,errorMessage.getFont().getSize());
    errorMessage.setFont(newLabelFont);
    closeError.setIcon(closeImage);
    closeError.setBounds(0,0,24,24);
    errorBg.setBounds(0,430,700,30);
    errorBg.setBackground(Color.lightGray);
    errorBg.add(closeError);
    errorBg.add(errorMessage);
    errorBg.setVisible(false);

    // Sets up Score/UI Portions of Screen
    resetBoard.setBounds(60,363,175,25);
    resetBoard.setVisible(true);
    resetBoard.addActionListener(this);

    // Set Up Board
    boardBg.setLayout(new GridLayout(rows,cols));
    boardBg.setBounds(300,50,350,350);
    for(int i=0; i<rows; i++) {
      for(int j=0; i<cols; j++) {
        block[i][j].setIcon(randomizer());
        block[i][j].addActionListener(this);
        boardBg.add(block[i][j]);
      }
    }

    mainFrame.getContentPane().add(boardBg);
    mainFrame.getContentPane().add(errorBg);
    mainFrame.getContentPane().add(resetBoard);

    //mainFrame.pack();
    mainFrame.setVisible(true);
  }


  /**
   *  Checks onClick event for which JButton was clicked
   *  and changes JButton.setIcon() accordingly.
   *
   *  @param  none
   *  @return none
   *  @see    java.awt.event.*
   *  @see    JButton
   *  @see    setIcon()
   *  @see    getIcon()
   *
   */
  public void actionPerformed(ActionEvent e) {

    if(e.getSource()==resetBoard) {
      System.out.println("Resetting");
      gameReset();
    }

    if(e.getSource()==errorBg || e.getSource()==errorMessage) {
      errorBg.setVisible(false);
    }
  }

  public void gameReset() {

    for(int i=0; i<rows; i++) {
      for(int j=0; i<cols; j++) {
        block[i][j].setIcon(randomizer());
      }
    }
  }

  public ImageIcon randomizer() {

    Random r = new Random();
    int rNum = r.nextInt(4);

    if(rNum==0) {
      return purpleBlock;
    } else if(rNum==1) {
      return redBlock;
    } else if(rNum==2) {
      return greenBlock;
    } else {
      return blueBlock;
    }
  }

  public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Blox().game();
      }
    });
  }
}

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 您是否对我昨天建议的 randomizer() 方法进行了这些修复?很高兴看到您尝试使用数组。接下来我们将研究布局管理器的使用和避免绝对定位。
  • @AndrewThompson:对不起。下次我会这样做。
  • 没问题。下次我会考虑你的问题。

标签: java swing nullpointerexception awt actionlistener


【解决方案1】:

问题可能来自你的循环:

    for(int i=0; i<rows; i++) {
        for(int j=0; i<cols; j++) {
            block[i][j].setIcon(randomizer());
            block[i][j].addActionListener(this);
            boardBg.add(block[i][j]);
        }
    }

block[i][j] 未初始化。首先像这样初始化它们:

    for(int i=0; i<rows; i++) {
        for(int j=0; i<cols; j++) {.
            block[i][j] = new JButton();
            block[i][j].setIcon(randomizer());
            block[i][j].addActionListener(this);
            boardBg.add(block[i][j]);
        }
    }

【讨论】:

  • 我不知道即使我做了JButton[][] block = new JButton[rows][cols],我仍然必须在循环中做block[i][j] = new JButton();。我添加了新行,但没有任何改变。仍然是同样的错误。
  • @pattmorter 是的,当您启动一个阵列时,您仍然必须创建阵列的每个单独实例。分配数组只提供内存空间来保存各个实例的指针。至于您的问题,错误不一样:ArrayIndexOutOfBoundsExceptionNullPointerException 不同。问题来自您的内部循环,它的条件不正确:i &lt; cols 实际上应该是j &lt; cols。您正在混合您的增量 ij
  • 哇。我什至没有注意到这一点。在这些固定宽度的字体中,有时很难注意到这些东西。
猜你喜欢
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
相关资源
最近更新 更多