有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么JPanel会在重新绘制时调整大小?

我的代码有一个问题:当我运行应用程序时,会显示添加到另一个JPanel的JPanel,但当父面板重新绘制时,子面板的大小会调整为10x10或类似的大小。 这是我的密码:

public class GUIv2 extends JPanel {
Vector<Section> sections = new Vector<>();
String backgroundImage = "";

public GUIv2(String bgImage) {
    backgroundImage = bgImage;
}

public void addSection(int id, int x, int y, int width, int height) throws RuntimeException {
    for(Section sec : sections) {
        if(sec.getId() == id) {
            throw new RuntimeException("The given ID is already registered.");
        }
    }
    sections.add(new Section(id));
    sections.lastElement().setBounds(100, 100, 100, 100);
    this.add(sections.lastElement());
    this.repaint();
}
public Section getSection(int id) {
    for(Section sec : sections) {
        if(sec.getId() == id) {
            return sec;
        }
    }
    return null;
}

protected void paintComponent(Graphics g) {
    try {
        g.drawImage(ImageIO.read(new File(backgroundImage)).getScaledInstance(getWidth(), getHeight(), 100), 0, 0, null);
    }
    catch(IOException e) {

    }
}
}

我希望有人能帮我解决这个问题。提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    该代码有几个大问题:

    1. 您正在对放置在不使用null布局的容器(JPanel)中的组件调用setBounds(...)。这意味着setBounds(...)可以按照您最初的要求显示,但不能在以后显示,或者根本不遵循它
    2. 您正在使用setBounds(...)。几乎总是(99%的时间)让组件的首选大小和容器的布局管理器处理组件的大小
    3. 在绘制方法期间,您正在读取图像,这不必要地降低了GUI的响应速度。为什么要不断地重读中的图像?相反,在创建组件时读取一次,将图像存储在变量中,而只需在绘制方法中绘制图像,这里paintComponent
    4. 您没有在覆盖方法中调用super.paintComponent(g),从而阻止Swing清理脏像素
    5. 忽略IO异常并将图像作为文件读取。最好是处理异常,至少通知它们,并将图像作为类资源而不是文件读入,因为这样可以将所有内容打包到JAR文件中,并且图像是可访问的

    所有这些都表明您尚未学习相关的教程。您可以在此处找到指向Swing教程和其他Swing资源的链接:Swing Info

    每当GUI重新调整大小时,布局管理器都会重新布局组件,所有设置的“边界”都会被忽略,从而导致组件收缩。有更好的方法来控制组件的大小和位置,如果不知道并了解您要创建的GUI,我们就无法推荐这些方法