首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Swing repaint() 不重繪的常見原因:內部類實例生命周期問題

     編輯:程式設計綜合問答

問題代碼核心片段

class ShowRadioButton extends JFrame {
    // ...
    class MessagePanel extends JPanel {
        // 繪製邏輯
        protected void left() { x -= 50; repaint(); }
        public void right() { x += 50; repaint(); }
    }
    class CreateButtonPanel extends JPanel {
        public CreateButtonPanel() {
            JButton leftBtn = new JButton("left");
            leftBtn.addActionListener(e -> {
                MessagePanel mp = new MessagePanel(); // 每次新建實例!
                mp.left();
            });
            // rightBtn 同理
        }
    }
}

根本原因

MessagePanel 定義為內部類,但在按鈕事件中 **每次點擊都 `new MessagePanel()`** 創建新實例。這導致:

  • 新實例未加入組件樹,不顯示於界面。
  • 原顯示的 MessagePanel 實例未收到 repaint() 調用。
  • 每次重繪操作針對的是不同對象,界面自然不更新。

修正方法

  1. 將繪製面板實例化為成員變量,確保全局唯一:
    class ShowRadioButton extends JFrame {
        private MessagePanel messagePanel = new MessagePanel(); // 唯一實例
        // ...
        class CreateButtonPanel extends JPanel {
            public CreateButtonPanel() {
                leftBtn.addActionListener(e -> messagePanel.left());
                rightBtn.addActionListener(e -> messagePanel.right());
            }
        }
    }
    
  2. 或在構造器中創建一次並保存引用,事件中直接調用該引用。

補充提示

  • repaint() 只是請求重繪,實際繪製在 EDT 執行 paintComponent,確保調用者是可見組件實例。
  • 避免在事件處理中創建新的 UI 組件實例,除非動態添加到容器並 revalidate()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved