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

重写JFrame的paint方法绘制背景后JLabel不显示的问题

问题:重写JFrame的paint方法添加背景图后,JLabel无法显示

我通过重写JFrame的paint方法添加了背景图片,但运行时添加的JLabel无法显示。移除背景图片后JLabel可正常显示,但我需要同时保留背景图与JLabel。


相关代码

public class startingPage extends JFrame {
    private JPanel contentPane;
    private String audioFileName = "bg-music.wav";
    private String imagePath = "truck_850x300_mining_island.png";
    private String logo = "explore_with_mine.png";

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    startingPage frame = new startingPage();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public startingPage() {
        initComponents();
        createEvents();
        playAudio();
    }

    public void playAudio() {
        // TODO Auto-generated method stub
        try 
        {
        File audioPath = new File(audioFileName);
        programManager.stream = AudioSystem.getAudioInputStream(audioPath);
        programManager.clip = AudioSystem.getClip();
        programManager.clip.open(programManager.stream);
        programManager.clip.start();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public void createEvents() {
    }

    public void initComponents() {
        setTitle("Explore With Mine");
        setIconImage(Toolkit.getDefaultToolkit().getImage(startingPage.class.getResource("/exploreWithMine/resources/logo.png")));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setBounds(400, 200, 720, 480);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        JButton btnNewButton = new JButton("START");
        btnNewButton.setBounds(262, 299, 177, 58);
        btnNewButton.setBackground(Color.LIGHT_GRAY);
        btnNewButton.setForeground(new Color(165, 42, 42));
        btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 42));
        contentPane.add(btnNewButton);
        JLabel lblNewLabel = new JLabel("TESTING");
        lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 16));
        lblNewLabel.setBounds(10, 10, 146, 43);
        contentPane.add(lblNewLabel);
    }

    public void paint(Graphics g) 
    {
        g.drawImage(new ImageIcon(imagePath).getImage(),-70,90, null);
    }
}

问题原因

重写JFrame的paint方法时,没有调用父类的super.paint(g),导致JFrame的子组件(JLabel、JButton等)的绘制逻辑被跳过,无法显示。另外,每次在paint方法中创建ImageIcon会重复加载图片,影响性能。


解决方案

方案一:修复现有paint方法

在paint方法中先调用父类方法绘制子组件,再绘制背景图,同时提前加载图片避免重复IO操作:

private Image backgroundImage;

public startingPage() {
    // 提前加载背景图
    try {
        backgroundImage = ImageIO.read(new File(imagePath));
    } catch (IOException e) {
        e.printStackTrace();
    }
    initComponents();
    createEvents();
    playAudio();
}

@Override
public void paint(Graphics g) 
{
    super.paint(g); // 先绘制子组件
    if(backgroundImage != null){
        g.drawImage(backgroundImage, -70, 90, this); // 最后绘制背景图
    }
}

方案二:推荐方案——重写JPanel的paintComponent

更符合Swing组件层次设计的做法是,自定义JPanel绘制背景,再将其作为内容面板:

public class startingPage extends JFrame {
    private JPanel contentPane;
    private String audioFileName = "bg-music.wav";
    private String imagePath = "truck_850x300_mining_island.png";
    private String logo = "explore_with_mine.png";
    private Image backgroundImage;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    startingPage frame = new startingPage();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public startingPage() {
        // 提前加载背景图
        try {
            backgroundImage = ImageIO.read(new File(imagePath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        initComponents();
        createEvents();
        playAudio();
    }

    public void playAudio() {
        try 
        {
        File audioPath = new File(audioFileName);
        programManager.stream = AudioSystem.getAudioInputStream(audioPath);
        programManager.clip = AudioSystem.getClip();
        programManager.clip.open(programManager.stream);
        programManager.clip.start();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public void createEvents() {
    }

    public void initComponents() {
        setTitle("Explore With Mine");
        setIconImage(Toolkit.getDefaultToolkit().getImage(startingPage.class.getResource("/exploreWithMine/resources/logo.png")));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setBounds(400, 200, 720, 480);
        
        // 创建自定义背景面板
        contentPane = new JPanel(){
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if(backgroundImage != null){
                    g.drawImage(backgroundImage, -70, 90, this);
                }
            }
        };
        
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        JButton btnNewButton = new JButton("START");
        btnNewButton.setBounds(262, 299, 177, 58);
        btnNewButton.setBackground(Color.LIGHT_GRAY);
        btnNewButton.setForeground(new Color(165, 42, 42));
        btnNewButton.setFont(new Font("Tahoma", Font.BOLD, 42));
        contentPane.add(btnNewButton);
        
        JLabel lblNewLabel = new JLabel("TESTING");
        lblNewLabel.setFont(new Font("Tahoma", Font.PLAIN, 16));
        lblNewLabel.setBounds(10, 10, 146, 43);
        contentPane.add(lblNewLabel);
    }
}

内容的提问来源于stack exchange,提问作者Saturo Gojo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:35:26