Java GridBagLayout未添加我的面板

Java GridBagLayout未添加我的面板,java,swing,layout-manager,paintcomponent,Java,Swing,Layout Manager,Paintcomponent,我正在尝试使用JFrame中的GridBagLayout添加三个面板。设置默认布局时,添加面板时不会出现任何问题,但当布局更改为GridBagLayout并在JFrame中添加面板时,则输出为空帧 以下是大型机的代码: public class MainFrame extends JFrame { CirclePanel[] cp; MainFrame() throws IOException{ cp = new CirclePanel[3];

我正在尝试使用
JFrame
中的
GridBagLayout
添加三个面板。设置默认布局时,添加面板时不会出现任何问题,但当布局更改为
GridBagLayout
并在
JFrame
中添加面板时,则输出为空帧

以下是大型机的代码:

public class MainFrame extends JFrame {
    CirclePanel[] cp;

    MainFrame() throws IOException{
        cp = new CirclePanel[3];
        for(int i = 0 ;i <3 ; i ++)
            cp[i]= new CirclePanel(i+1);

        this.setSize(700, 700);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setLayout(new GridBagLayout());//when this line is not set then 
                                       //add(cp[0]) adds the panel
        GridBagConstraints gc = new GridBagConstraints();
        gc.weightx=1;
        gc.weighty=1;
        gc.gridx=0;
        gc.gridy=0;

        add(cp[1],gc);

        this.setVisible(true);
    }
}

我通过增加
gridx
值来添加所有3个面板。为了让它发挥作用,我做了以下几点:

  • 添加了行
    gc.fill=GridBagConstraints。这两行都允许面板调整大小并填充额外空间

  • 在面板的构造函数中调用
    setBackground
    ,而不是在
    paintComponent
    中调用
    fillRect
    。它省去了计算面板大小的麻烦

  • 覆盖面板的
    getPreferredSize

    @Override
    public Dimension getPreferredSize() {
    
        int size = (int) (2 * mainCircler * ampRadius);
        return new Dimension(size, size);
    }
    
    (您可能需要重新计算。)

  • 在框架上调用
    pack
    ,而不是
    setSize

  • 解释

    从布局管理器的角度来看,要添加到框架中的面板是空的-它们没有任何子组件。这意味着面板将保留默认的首选is,即10x10(
    System.out.println(cp[1].getPreferredSize())
    ),并将它们添加到具有这些尺寸的框架中

    计算构件的首选尺寸时,不会自动考虑自定义绘制。如果首选尺寸对于绘画来说太小,则不会显示(或仅显示部分)。覆盖面板的
    getPreferedSize
    方法以提供正确的尺寸,将告诉框架在调用
    pack
    时如何显示这些尺寸

    编辑:评论回答

    当我调用
    setBackground
    在构造器中为面板上色时,效果很好,但当我尝试在
    paintComponent
    中使用
    fillRect
    时,第一个面板上色,但接下来的两个面板不上色。为什么呢

    因为一个非常常见的误解(这就是为什么我推荐第2点)

    getXXX()
    X
    Y
    Width
    Height
    )没有明确说明以下内容,但它们是从
    getBounds()
    派生的,其内容如下:

    矩形
    对象的形式获取此组件的边界。边界指定此组件相对于其父组件的宽度、高度和位置

    (强调我的。)因此边界在父坐标系中。但是,
    Graphics.fillRect
    使用组件坐标系中的给定边界进行绘制(传递到
    paintComponent
    Graphics
    对象用于绘制组件,而不是其父对象)

    然后为了在自己的坐标系中绘制面板,我们需要

    g2d.fillRect(0, 0, getWidth(), getHeight());
    
    因为组件在其自己的坐标系中总是从
    (0,0)
    开始。使用

    g2d.fillRect(getX(), getY(), getWidth(), getHeight());
    
    获取面板在父面板中的位置,并将其传递到面板中的某个非特殊位置。此外,如果面板位于父级的
    (300300)
    ,但面板的大小小于
    (300300)
    ,则面板中的图形理论上将从面板外部开始。所以,你看不到画


    第一个面板绘制是因为它的
    (0,0)
    与其父面板的
    (0,0)

    一致。请考虑提供一个示例来说明您的问题。这不是一个代码转储,而是您正在做的一个示例,它突出了您所遇到的问题。这将减少混乱和更好的响应当这些事情发生在我身上时,我要做的第一件事就是添加
    setboorder(newlineborder(Color.RED))或更改组件的背景色,以查看是否实际添加了该组件。其次,您的
    CirclePanel
    应该覆盖
    getPreferredSize
    ,并返回一些指示,说明to通常希望有多大。您还可以添加
    gc.fill=GridBagConstraints。两者都是
    以强制面板占用整个可用单元格空间。我总结了我的问题@MadProgrammer.对不起,但现在情况更糟了。问题不在于
    GridBagLayout
    ,而在于
    CirclePanel
    ,但是您没有包括
    MakeArrays
    ,这使得无法100%确定问题或如何最好地解决问题。MakeArrays类只是从文件中获取值,并在int-array@MadProgrammerit中转换这些值,非常感谢您的解释。我有一个更简单的问题,当我调用
    setBackground
    在面板的构造函数中为面板着色时,它可以正常工作,但当我尝试在
    paintComponent
    中使用
    fillrect
    ,然后添加
    GridBagLayout
    时,第一个面板会着色,但接下来的两个面板不会着色。为什么会这样?感谢您的解释,这真的很有帮助,可以清楚地了解组件的位置。
    g2d.fillRect(getX(), getY(), getWidth(), getHeight());