Java Swing继承JPanel后paint、paintComponent方法未被调用如何解决
问题根源
你的paintComponent方法未被触发的核心原因是自定义的Board(JPanel子类)实例没有被添加到JFrame的显示容器中,Swing只会绘制被纳入容器层级的组件。除此之外还有几个写法错误也会影响绘制逻辑:
- 你重写了JComponent自带的
getWidth()、getHeight()方法,会干扰JPanel自身的尺寸计算 - 重写
paintComponent时没有先调用super.paintComponent(g),会丢失组件默认绘制逻辑、容易出现残影 - 同时重写
paint和paintComponent会导致绘制逻辑冲突,常规自定义绘制仅需重写paintComponent即可 - 未按Swing规范在事件分发(EDT)线程初始化UI,可能引发未知的显示异常
修复步骤
- 在
initBoard方法中,将当前Board实例(this)添加到JFrame的内容面板中 - 删除自定义的
getWidth、getHeight方法,改用JPanel自带的setPreferredSize设置组件尺寸 - 仅保留
paintComponent重写,方法开头补充super.paintComponent(g)调用 - 把UI初始化逻辑放到EDT线程执行
修复后完整代码
import java.awt.*; import javax.swing.*; public class Main { public static void main(String[] args) { // Swing UI必须在EDT线程初始化 SwingUtilities.invokeLater(() -> { Board board = new Board(295, 295, "Go board"); }); } } class Board extends JPanel{ private String title; private JFrame frame; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public JFrame getFrame() { return frame; } public void setFrame(JFrame frame) { this.frame = frame; } public Board(int width, int height, String title){ super(); // 设置面板首选尺寸 this.setPreferredSize(new Dimension(width, height)); this.title = title; this.initBoard(); } public Board(){ super(); } public void initBoard(){ JFrame f = new JFrame(this.getTitle()); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 将当前面板加入JFrame容器 f.add(this); f.getContentPane().setBackground(Color.getHSBColor(25, 75, 47)); // 自动适配组件尺寸 f.pack(); f.setLocation(550, 25); f.setVisible(true); this.setFrame(f); } @Override // 加注解避免重写签名错误 public void paintComponent(Graphics g) { // 调用父类方法完成默认绘制 super.paintComponent(g); g.drawLine(10, 10, 250, 10); System.out.println("Test paintComponent"); } }
内容的提问来源于stack exchange,提问作者a.v
相关产品推荐
相关产品推荐

