Swing中repaint方法导致窗体异常重复显示问题
问题根源与解决方案
首先,你的代码里有两个核心问题直接导致了UI崩溃、重复显示和背景不渲染的现象,咱们一步步拆解解决:
1. 无限重绘循环(崩溃/重复显示的元凶)
你在paint()方法里调用了repaint()——这会触发一个死循环:
repaint()会请求Swing框架重新调用组件的paint()方法- 每次
paint()执行时又会再次调用repaint() - 往复循环会疯狂消耗CPU和内存,最终导致UI崩溃或持续闪烁
解决方法:直接删掉paint()里的repaint()调用。如果需要动态更新绘制内容,只需要在修改图形数据的时候(比如添加新图形、修改已有图形的位置/颜色)主动调用repaint()即可,比如:
// 当你需要添加新图形时: panelPovrsina.getListaOblika().add(new Kvadrat(new Tacka(100,100), 30, "plava", "crna")); panelPovrsina.repaint(); // 仅在数据变化时触发重绘
2. 未渲染组件默认背景
Swing的paint()方法负责绘制组件的默认内容(包括背景、边框),你重写paint()但没有调用super.paint(g),导致你设置的白色背景根本不会被绘制出来。
更规范的优化:对于JPanel这类轻量级组件,推荐重写paintComponent()而不是paint()——这是Swing自定义绘制的标准实践,专门用于绘制组件的内部内容,同时能保留组件的默认渲染逻辑。
修正后的完整代码
import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; import java.util.Iterator; import javax.swing.JPanel; public class PanelPovrsina extends JPanel{ private ArrayList<Oblik> listaOblika; public PanelPovrsina() { this.listaOblika = new ArrayList<Oblik>(); this.listaOblika.add(new Kvadrat(new Tacka(50, 50), 50, "zuta", "crvena")); this.setBackground(Color.WHITE); // JPanel默认就是可见的,不需要手动setVisible(true),添加到JFrame后会自动显示 } // 重写paintComponent而非paint,这是Swing自定义绘制的标准方式 @Override protected void paintComponent(Graphics g) { // 先调用父类方法,确保背景、边框等默认内容被正确绘制 super.paintComponent(g); if(this.listaOblika.isEmpty()) return; Iterator<Oblik> it = this.listaOblika.iterator(); while(it.hasNext()) { it.next().crtajUBoji(g); } // 这里绝对不能加repaint()! } public ArrayList<Oblik> getListaOblika() { return this.listaOblika; } }
额外注意事项
- 永远不要在
paint/paintComponent里做耗时操作,也不要调用会触发重绘的方法(比如repaint()) - 如果你的
Oblik和Kvadrat类涉及到修改图形属性(比如移动位置、改变颜色),记得在修改后调用repaint()来刷新UI - 不需要在JPanel的构造方法里调用
setVisible(true),当你把它添加到JFrame并设置JFrame可见后,面板会自动显示
内容的提问来源于stack exchange,提问作者sebamed
相关产品推荐
相关产品推荐

