Swing中Graphics2D绘图空白的主因是未调用super.paintComponent(g),导致背景未擦除、双缓冲失效;须在paintComponent开头调用该方法,再转为Graphics2D并启用抗锯齿。
Swing 里用 Graphics2D 绘图为什么画不出来?
常见现象是重写了 paintComponent(),但调用 g.drawLine() 或 g.fillOval() 后界面空白。根本原因是没调用 super.paintComponent(g),导致背景未擦除、双缓冲失效,或组件未正确触发重绘流程。
实操要点:
- 必须在
paintComponent(Graphics g)开头写super.paintComponent(g) - 强制类型转换为
Graphics2D再开启抗锯齿:Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - 不要在其他地方(如按钮点击中)直接保存
Graphics引用——它只在绘制周期内有效,拿出去用会抛NullPointerException或静默失败
鼠标拖拽画线时坐标偏移、断线怎么办?
典型错误是用 getMousePosition() 获取全局坐标,或没处理组件缩放/滚动条偏移。真实绘制必须基于组件坐标系,且需区分“按下”“拖动”“释放”三个状态。
关键处理逻辑:
立即学习“Java免费学习笔记(深入)”;
- 在
mousePressed中记录startX = e.getX(); startY = e.getY(); - 在
mouseDragged中累加线段:lines.add(new Line2D.Double(lastX, lastY, e.getX(), e.getY())); lastX = e.getX(); lastY = e.getY(); - 避免用
mouseMoved——它不捕获拖拽,只会响应悬停;拖拽必须用mouseDragged - 如果容器加了
BorderLayout或嵌套滚动,确保监听器注册在实际绘图的JPanel上,而非外层窗口
如何让绘制图形支持选中、移动和删除?
不能靠像素碰撞检测,得给每个图形对象封装边界与状态。推荐用 Shape 接口(如 Rectangle2D、Ellipse2D)统一管理,再配合 contains(double x, double y) 判断点击是否命中。