You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:54:33