【问题标题】:NullPointerException with BufferedImage Array带有 BufferedImage 数组的 NullPointerException
【发布时间】:2013-01-06 02:30:43
【问题描述】:

我正在尝试拍摄图像并将其转换为在 GridLayout 中布局的图块,但收到运行时错误。

代码如下:

public class TileList extends JPanel {

private static final int width = 16;            //width of a tile
private static final int height = width;
private int col = 1;
private int row = 1;

private BufferedImage image;
File tilesetImage = new File("image.png");
BufferedImage tileset[];

public void loadAndSplitImage (File loadImage) {
    try{
        image = ImageIO.read(loadImage);
    }catch(Exception error) {
        System.out.println("Error: cannot read tileset image.");
    }// end try/catch
    col = image.getWidth()/width;
    row = image.getHeight()/height;
    BufferedImage tileset[] = new BufferedImage[col*row];
}// end loadAndSplitImage

public TileList() {
    loadAndSplitImage(tilesetImage);
    setLayout(new GridLayout(row,col,1,1));
    setBackground(Color.black);

    int x=0;
    int y=0;
    for (int i = 0; i < (col*row); i++) {
        JPanel panel = new JPanel();
        tileset[i] = new BufferedImage(width, height, image.getType());  //first error
        tileset[i] = image.getSubimage(x,y,x+width,y+height);
        panel.add(new JLabel(new ImageIcon(tileset[i])));
        add(panel);
        x+=width;
        y+=height;
    }// end for loop
}// end constructor

public static void createAndShowGui() {
    JFrame frame = new JFrame("TileList");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new TileList());      //second error
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}//end createAndShowGui

public static void main (String [] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run () {
            createAndShowGui();           //third error
        }// end run
    });// end invokeLater
  }// end main
}// end class

这是我收到的错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at TileList.<init>(TileList.java:55)
    at TileList.createAndShowGui(TileList.java:73)
    at TileList$1.run(TileList.java:82)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:682)
    at java.awt.EventQueue$3.run(EventQueue.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDo
main.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
ad.java:244)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:163)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:151)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)

    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)

    at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

这个错误是什么意思,我是怎么写错代码的?

编辑:我按照 Hovercraft 的建议更改了代码,但是现在出现了新错误:

tileset[] = new BufferedImage[col*row];
       ^                           error: not a statement

tileset[] = new BufferedImage[col*row];
         ^                         error: ';' expected

tileset[] = new BufferedImage[col*row];
                             ^     error: not a statement

【问题讨论】:

  • 这是一个NullPointerException,你并没有告诉我们最重要的信息——哪一行抛出它,哪一行是TileList.java:55

标签: java arrays nullpointerexception bufferedimage awt-eventqueue


【解决方案1】:

你的错误是你正在隐藏一个变量——当你已经在类中声明了变量 tileSet 时,你在构造函数中重新声明了它。因此,类中声明的 tileSet 变量永远不会被初始化,因为只有局部变量,即在构造函数中声明的变量被初始化。

解决方案:在类中只声明一次tileSet。

因此,不要这样做:

public class TileList extends JPanel {

  //.... deleted for brevity

  BufferedImage tileset[];

  public void loadAndSplitImage (File loadImage) {
    try{
        image = ImageIO.read(loadImage);
    }catch(Exception error) {
        System.out.println("Error: cannot read tileset image.");
    }// end try/catch
    col = image.getWidth()/width;
    row = image.getHeight()/height;
    BufferedImage tileset[] = new BufferedImage[col*row]; // *** re-declaring variable!
  }

而是这样做:

public class TileList extends JPanel {

  //.... deleted for brevity

  BufferedImage tileset[];

  public void loadAndSplitImage (File loadImage) {
    try{
        image = ImageIO.read(loadImage);
    }catch(Exception error) {
        System.out.println("Error: cannot read tileset image.");
    }// end try/catch
    col = image.getWidth()/width;
    row = image.getHeight()/height;

    // ************
    // BufferedImage tileset[] = new BufferedImage[col*row]; // *****
    tileset[] = new BufferedImage[col*row]; // **** note the difference? ****
  }

请注意,比解决这个孤立问题更重要的是了解如何解决 NPE (NullPointerExceptions)。关键是检查抛出异常的行上的所有变量,检查哪些是空的,然后在尝试使用之前回头看看其中一个没有正确初始化。

【讨论】:

  • 当我将行移到声明类变量的位置时,我必须取出 [i] 并替换为 []。这会导致不兼容类型的另一个错误 'BufferedImage tileset[] = new BufferedImage(width,height,image.getType());'
  • @Emily:不,不要移动这条线,只是不要重新声明变量。请参阅我上面的编辑。尝试为 BufferedImage array 分配一个 BufferedImage 是没有意义的。
  • 哦,我没有意识到我正在重新声明它。我查看了您的新编辑并像您一样在tileset之前删除了“BufferedImage”,但现在整行都有错误:不是声明
  • @Emily:如果您发现错误,最好将其显示给我们,否则我们将无法为您提供帮助。
  • @Emily:tileset 已被声明为数组。为什么在分配变量时使用[]?没有意义,所以摆脱它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
相关资源
最近更新 更多