绘制国际象棋棋子时触发IllegalArgumentException:图片无法找到
国际象棋棋子图片加载失败:input == null异常
异常信息
Exception in thread "main" java.lang.IllegalArgumentException: input == null! at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1358) at main.pieces.Piece.<init>(Piece.java:21) at main.pieces.Knight.<init>(Knight.java:8) at main.Board.addPieces(Board.java:23) at main.Board.<init>(Board.java:19) at main.App.main(App.java:14)
问题描述
尝试自定义棋盘绘制国际象棋棋子,但始终提示图片无法找到。已尝试移动res文件夹、确认文件为PNG格式,但问题依旧。
相关代码
App.java
package main; import javax.swing.*; import java.awt.*; public class App { public static void main(String[] args) throws Exception { JFrame frame = new JFrame(); frame.getContentPane().setBackground(new Color(30, 30, 30)); frame.setLayout(new GridBagLayout()); frame.setMinimumSize(new Dimension(1000, 1000)); frame.setLocationRelativeTo(null); Board board = new Board(); frame.add(board); frame.setVisible(true); } }
Board.java
package main; import main.pieces.Piece; import main.pieces.Knight; import javax.swing.*; import java.awt.*; import java.util.ArrayList; public class Board extends JPanel { public int tileSize = 85; int cols = 8; int rows = 8; ArrayList<Piece> pieceList = new ArrayList<>(); public Board() { this.setPreferredSize(new Dimension(cols * tileSize, rows * tileSize)); addPieces(); } public void addPieces() { pieceList.add(new Knight(this, 2, 0, false)); } public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; for (int r = 0; r < rows; r++) for (int c = 0; c < cols; c++) { g2d.setColor((c + r) %2 == 0 ? new Color(230, 230, 230) : new Color(0, 0, 0)); g2d.fillRect(c * tileSize, r * tileSize, tileSize, tileSize); } for (Piece piece : pieceList) { piece.paint(g2d); } } }
Piece.java
package main.pieces; import main.Board; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; public class Piece { public int col, row; public int xPos, yPos; public boolean isWhite; public String name; public int value; BufferedImage sheet; { try { sheet = ImageIO.read(ClassLoader.getSystemResourceAsStream("pieces.png")); } catch (IOException e) { e.printStackTrace(); } } protected int sheetScale = sheet.getWidth() / 6; Image sprite; Board board; public Piece(Board board) { this.board = board; } public void paint(Graphics2D g2d) { g2d.drawImage(sprite, xPos, yPos, null); } }
Knight.java
package main.pieces; import main.Board; import java.awt.image.BufferedImage; public class Knight extends Piece { public Knight(Board board, int col, int row, boolean isWhite) { super(board); this.col = col; this.row = row; this.xPos = col * board.tileSize; this.yPos = row * board.tileSize; this.isWhite = isWhite; this.name = "Knight"; this.sprite = sheet.getSubimage(3 * sheetScale, isWhite ? 0 : sheetScale, sheetScale, sheetScale).getScaledInstance(sheetScale, sheetScale, BufferedImage.SCALE_SMOOTH); } }
解决方法
1. 确认资源文件的正确位置
ClassLoader.getSystemResourceAsStream("pieces.png")会从类路径的根目录查找文件,所以要确保文件处于正确位置:
- 普通Java项目:将
pieces.png直接放到src目录下,或者在IDE中把存放图片的文件夹标记为「资源目录」。 - Maven/Gradle项目:将图片放到
src/main/resources目录下,编译后文件会自动进入类路径根目录。
2. 更换更可靠的资源加载方式
用当前类的ClassLoader加载资源,避免系统类加载器的路径问题,修改Piece类中的初始化块代码:
{ try { // 用当前类的getResourceAsStream,/表示类路径根目录 sheet = ImageIO.read(Piece.class.getResourceAsStream("/pieces.png")); } catch (IOException e) { e.printStackTrace(); } }
3. 检查文件有效性
- 确认文件名完全匹配(包括大小写,比如系统区分大小写时
Pieces.png和pieces.png是不同文件)。 - 验证
pieces.png是未损坏的有效PNG文件,可以用图片查看器打开确认。
4. 确认资源已被复制到编译目录
检查项目编译后的输出文件夹(比如bin或target/classes),确认pieces.png存在其中。如果不存在,需要在IDE中配置:将资源文件设置为编译时需要复制的文件。
内容的提问来源于stack exchange,提问作者Anthony McKinney
相关产品推荐
相关产品推荐

