MouseListener方法触发NullPointerException问题排查
嘿,我来帮你搞定这个首次点击就触发NullPointerException的问题~
首先,大概率是你代码里存储点击点的容器(比如数组或列表)没初始化,或者是绘图相关的组件实例没创建就绑定了鼠标监听。我结合你给出的代码片段,整理了修复后的完整版本,顺便把逻辑补全了:
修复后的完整代码
import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JPanel; public class TriangleClicker extends JFrame { private final int width = 700; private final int height = 500; // 关键:初始化存储点击点的列表,避免空指针 private List<Point> clickPoints = new ArrayList<>(); public TriangleClicker() { setTitle("Click to Draw"); setSize(width, height); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // 创建绘图面板并绑定鼠标监听 DrawingPanel panel = new DrawingPanel(); panel.addMouseListener(new ClickListener()); add(panel); } // 自定义绘图面板 private class DrawingPanel extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // 必须先调用父类方法,清理画布 g.setColor(Color.BLACK); // 根据点击次数绘制对应图形 switch (clickPoints.size()) { case 1: // 绘制单个点 Point p1 = clickPoints.get(0); g.fillOval(p1.x - 3, p1.y - 3, 6, 6); break; case 2: // 绘制两点连线 Point pA = clickPoints.get(0); Point pB = clickPoints.get(1); g.drawLine(pA.x, pA.y, pB.x, pB.y); // 同时保留两个顶点的绘制 g.fillOval(pA.x - 3, pA.y - 3, 6, 6); g.fillOval(pB.x - 3, pB.y - 3, 6, 6); break; case 3: // 绘制三角形 Point t1 = clickPoints.get(0); Point t2 = clickPoints.get(1); Point t3 = clickPoints.get(2); g.drawPolygon(new int[]{t1.x, t2.x, t3.x}, new int[]{t1.y, t2.y, t3.y}, 3); // 绘制三个顶点 g.fillOval(t1.x - 3, t1.y - 3, 6, 6); g.fillOval(t2.x - 3, t2.y - 3, 6, 6); g.fillOval(t3.x - 3, t3.y - 3, 6, 6); break; default: // 点击次数≥4时重置 clickPoints.clear(); repaint(); } } } // 鼠标监听类 private class ClickListener implements MouseListener { @Override public void mouseClicked(MouseEvent e) { // 记录点击点 clickPoints.add(e.getPoint()); // 四次点击后重置 if (clickPoints.size() >= 4) { clickPoints.clear(); } // 触发重绘 repaint(); } // 其他未用到的监听方法,必须实现(因为是MouseListener接口) @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} } public static void main(String[] args) { // 在事件调度线程中启动GUI,避免线程安全问题 javax.swing.SwingUtilities.invokeLater(() -> { new TriangleClicker().setVisible(true); }); } }
关键修复点说明
- 初始化存储点的列表:我加了
private List<Point> clickPoints = new ArrayList<>();,这是解决首次点击空指针的核心——原来的代码里大概率这个变量只声明了没初始化,首次点击添加元素时就会报错。 - 正确绑定鼠标监听:确保先实例化
DrawingPanel,再给它加监听,避免组件为null时调用addMouseListener。 - 规范绘图逻辑:重写
paintComponent时必须先调用super.paintComponent(g),否则会出现绘图残留的问题;同时按点击次数分情况处理图形绘制,逻辑更清晰。 - 完善监听接口实现:
MouseListener是接口,必须实现所有方法,哪怕是空实现,否则编译会报错。
你可以直接运行这段代码试试:单击画点,两次单击画线,三次单击画三角形,第四次单击就会清空画布重置~
内容的提问来源于stack exchange,提问作者Keegan Moore
相关产品推荐
相关产品推荐

