尽管 JPanel 的 setPreferredSize 未调用 PaintComponent()

PaintComponent() not called despite setPreferredSize of JPanel

我试图理解为什么下面的短代码不起作用。 我知道当没有 Layout 或组件的大小为 0 时,不会调用 paint 组件方法。

但这里不是这种情况。

你能解释一下为什么我不能为此设置背景吗?

public class Login extends JPanel {

    private BufferedImage bgImage;

    public Login() {
        super();
        initImages();
        setLayout(new BorderLayout());

        setPreferredSize(new Dimension(600, 600));
        add(new JLabel("Hi"), BorderLayout.CENTER);
    }

    private void initImages() {
        try {
            bgImage = ImageIO.read(new File("images/login.jpg"));
            System.out.println("image loaded");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("image not loaded");
        }
    }

    @Override
    public void paintComponents(Graphics g) {
        super.paintComponents(g);
        g.drawImage(bgImage, 0, 0, null);
        System.out.println("repaint");
    }

    public static void createAndShowGui() {
        JFrame frame = new JFrame();
        Login login = new Login();
        frame.add(login, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

如果你想让它工作,那么你需要改变...

@Override
public void paintComponents(Graphics g) {
    super.paintComponents(g);
    g.drawImage(bgImage, 0, 0, null);
    System.out.println("repaint");
}

更像是...

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(bgImage, 0, 0, this);
}

paintComponent负责绘制组件的"bottom"层,paintComponents负责绘制子层