如何从paintComponent()向GridBagLayout添加元素

问题描述

在下面的代码中,在构造函数中,标签被正确创建并显示在屏幕上。请注意,它已添加GridBagLayout() 布局管理器。然后,在我们从 JPanel 扩展覆盖的 paintComponent() 方法中,我们重置 JPanel 的内容并再次添加标签。但是,这次标签没有显示在屏幕上。我希望它可以正常添加,但事实并非如此。为什么会这样?

public class MyPanel extends JPanel {

    private final GridBagConstraints grid = new GridBagConstraints();

    public MyPanel () {
        setBounds(200,200,1000,1000);
        setLayout(new GridBagLayout());
        setopaque(false);
        setVisible(false);

        grid.anchor = GridBagConstraints.PAGE_END;

        JLabel oldLabel = new JLabel("This is an old Label");
        add(oldLabel,grid);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        removeAll();

        JLabel newLabel = new JLabel("This is a new Label");
        add(newLabel,grid);

        revalidate();
        repaint();
    }

}

在这个例子中,组件是已知的,但在我的情况下,我有可变数量的组件,这些组件事先不知道并且在程序中发生变化。

解决方法

就像对我的问题的评论一样,我的方法不正确。

在任何情况下都不应paintComponent创建、添加或删除组件。绘画是由系统触发的,原因有很多,包括看似微不足道的事件,比如在窗口上移动鼠标。另外,永远不要从paintComponent 方法调用repaint;这迫使 Swing 最终再次调用paintComponent,这意味着您已经创建了一个无限循环。

解决方案是将组件添加到面板并在面板上调用 revalidate()