【问题标题】:Problems with adding a picture with JLabel使用 JLabel 添加图片的问题
【发布时间】:2025-12-02 04:05:03
【问题描述】:

我正在为我的高中计算机科学课(一个非常平庸的口袋妖怪游戏)做一个期末项目,我在添加一个带有 ImageIcon 的 Jlabel 的 switch 语句时遇到了问题。

当我运行驱动程序并打开此面板时,它应该添加一个随机对手,这就是 switch 语句的用途,它根据对手是谁为 oppHP 变量提供一个值。底部的 PaintComponent 设置背景图像。问题是当我运行它时,没有对手的图片显示它只是背景图片。

请记住,我对编码非常陌生,所以我可能无法理解解释,换句话说,如果不是太麻烦,请尽量保持简单。谢谢!

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Lucario extends JPanel {

    private int myHP;
    private int oppHP;
    private boolean ok;
    private int rand;
    private JButton olabel;
    private JButton mlabel;

    public Lucario() {
        ImageIcon lIcon = new ImageIcon("opplucario.png");
        ImageIcon sIcon = new ImageIcon("oppsylveon.png");
        ImageIcon cIcon = new ImageIcon("oppcharizard.png");
        ImageIcon grIcon = new ImageIcon("oppgreninja.png");
        ImageIcon geIcon = new ImageIcon("oppgengar.png");
        ImageIcon mIcon = new ImageIcon("oppmystery.png");
        for (int k = 0; k < 1; k++) {
            rand = (int) (Math.random() * 6);

        }
        switch (rand) {

            case 0:

                JLabel l = new JLabel();
                l.setIcon(lIcon);
                add(l);

                oppHP = 344;
                break;
            case 1:

                JLabel s = new JLabel();
                s.setIcon(sIcon);
                add(s);
                oppHP = 394;
                break;
            case 2:

                JLabel c = new JLabel();
                c.setIcon(cIcon);
                add(c);
                oppHP = 360;
                break;
            case 3:

                JLabel gr = new JLabel();
                gr.setIcon(grIcon);
                add(gr);
                oppHP = 348;

                break;
            case 4:

                JLabel ge = new JLabel();
                ge.setIcon(geIcon);
                add(ge);
                oppHP = 324;
                break;
            case 5:

                JLabel m = new JLabel();
                m.setIcon(mIcon);
                add(m);
                oppHP = 400;
                break;
        }

        myHP = 344;
        this.setLayout(null);
        olabel = new JButton("HP: " + oppHP);
        olabel.setFont(new Font("Serif", Font.BOLD, 20));
        olabel.setBounds(70, 100, 150, 40);
        olabel.setOpaque(false);
        olabel.setContentAreaFilled(false);
        olabel.setBorderPainted(false);
        add(olabel);
        mlabel = new JButton("HP: " + myHP);
        mlabel.setFont(new Font("Serif", Font.BOLD, 20));
        mlabel.setBounds(350, 330, 150, 40);
        mlabel.setOpaque(false);
        mlabel.setContentAreaFilled(false);
        mlabel.setBorderPainted(false);
        add(mlabel);

    }

    public void paintComponent(Graphics g) {

        ImageIcon Backg = new ImageIcon("playbg.png");
        g.drawImage(Backg.getImage(), 0, 0, 590, 590, this);

    }

}

【问题讨论】:

  • 图像存储在哪里? paintComponent 应该是 protected,任何人都不应该有任何理由打电话给它。按照惯例,您应该在进行任何自定义绘画之前致电super.paintComponent
  • 欢迎来到 Stack Overflow!不要使用null 布局。像素完美布局是现代 UI 设计中的一种错觉,您无法控制字体、DPI、渲染管道或其他会改变组件在屏幕上渲染方式的因素。 Swing 旨在与布局管理器一起克服这些问题。如果您坚持忽略这些功能并违背 API 设计,请准备好迎接许多令人头疼的问题和永无止境的辛勤工作......

标签: java swing jlabel paintcomponent imageicon


【解决方案1】:

主要问题是您使用null 布局,例如...

JLabel m = new JLabel();
m.setIcon(mIcon);
add(m);

m默认没有大小或位置信息(0x0@0x0

适当的答案是使用一个或多个适当的布局管理器

【讨论】:

    【解决方案2】:
    public void paintComponent(Graphics g) {
        ImageIcon Backg = new ImageIcon("playbg.png");
    

    应该是:

    public void paintComponent(Graphics g) { 
        super.paintComponent(g); 
    
    1. 覆盖绘制中的第一个调用应该是超级方法。
    2. 图像应作为类成员加载和缓存。永远不要尝试在应该很快完成的绘制方法中加载资源。

    一般提示

    1. 到部署时,这些资源可能会变成。在这种情况下,资源必须由URL 而不是File 访问。请参阅标签的info page,了解形成URL 的方法。
    2. Java GUI 可能必须在多个平台、不同的屏幕分辨率和使用不同的 PLAF 上工作。因此,它们不利于组件的精确放置。要为强大的 GUI 组织组件,请改用布局管理器或 combinations of them1,以及 white space2 的布局填充和边框。

    【讨论】: