Java AWT:设置 Canvas 的背景会更改整个框架的背景

Java AWT: Setting background of Canvas changes the background for the whole frame

为什么更改 java.awt.Canvas 的背景颜色会更改整个框架的背景?

我设置了一个Frame对象如下:

public class Gui extends Frame {

    public Gui() {

        setSize(800, 600);
        setLocation(0, 0);

        Canvas cd=new Canvas();
        cd.setSize(500, 300);
        cd.setBackground(Color.BLUE);
        add(cd);


        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent arg0) {
                System.exit(0);
            }

        });
    }

    @Override
    public void paint(Graphics g) {
        paintComponents(g);
    }

    public static void main(String[] args) {

        Gui g=new Gui();
        g.setVisible(true);

    }

}

上面的代码将帧大小设置为 800x600,然后添加一个小得多的 canvas - 500x300,最后将背景颜色设置为 Color.BLUE,但不是得到一个更大的 800x600 window 框架内的 500x300 蓝色矩形(默认为灰色),结果是带有蓝色背景的 800x600 框架:

文档说:

public void setBackground(Color c)

Sets the background color of this component.

The background color affects each component differently and the parts of the component that are affected by the background color may differ between operating systems.

这可能是问题所在(我在 Ubuntu 上运行)?
或者我在这里遗漏了什么?

Frame 的默认布局是 BorderLayout(尽管许多使用基于 AWT 的示例代码 Frame class 是在默认布局为 FlowLayout)。如果没有布局约束,添加到 BorderLayout 的组件将在 CENTER 约束中结束,该约束会拉伸组件以使其适合可用的高度和宽度。

我们可能会使用 GridBagLayout。当我们在没有任何约束的情况下将单个组件添加到 GridBagLayout 时,它将居中并且大小将得到遵守。例如。 (请参阅代码中的更多注释。)

import java.awt.*;
import java.awt.event.*;

public class Gui extends Frame {

    public Gui() {
        setSize(400, 200);
        setLocationByPlatform(true);
        setLayout(new GridBagLayout());

        Canvas cd=new Canvas();
        // TODO: Override rather than set & make it preferred rather than actual
        cd.setSize(300, 100); 
        cd.setBackground(Color.BLUE);
        add(cd);

        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent arg0) {
                System.exit(0);
            }
        });
    }

    @Override
    public void paint(Graphics g) {
        //paintComponents(g); // wrong method!
        super.paint(g); // right method, but does nothing different to original!
    }

    public static void main(String[] args) {
        // TODO: AWT/Swing based GUIs should be started on the EDT
        Gui g=new Gui();
        g.setVisible(true);
    }
}