Swing 组件在自定义布局管理器中不可见

Swing components are not visible in custom layout manager

我制作了以下布局管理器class:

public class MainFrameLayout extends BorderLayout
{
    private final JPanel north, center, south;

    /**
     * Constructor for this layout.
     */
    public MainFrameLayout()
    {
        super();

        north = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
        center = new JPanel();
        center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
        south = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));

        north.setVisible(true);
        center.setVisible(true);
        south.setVisible(true);

        super.addLayoutComponent(north, NORTH);
        super.addLayoutComponent(center, CENTER);
        super.addLayoutComponent(south, SOUTH);
    }

    @Override
    public void addLayoutComponent(Component comp, Object constraints)
    {
        if (!(constraints instanceof MainFrameLayoutConstraints))
            throw new IllegalArgumentException("Invalid constraints");

        switch ((MainFrameLayoutConstraints) constraints)
        {
            case NORTH:
                north.add(comp);
                break;

            case CENTER:
                center.add(comp);
                break;

            case SOUTH:
                south.add(comp);
                break;
        }
    }
}

MainFrameLayoutConstraints 是通用的 enum class,只有 NORTHCENTERSOUTH 变体。

我试图在以下应用程序中使用此布局:

public class MyApplication extends JFrame
{
    private final JFormattedTextField caseNumberBox;

    public MyApplication()
    {
        super("A Title Thingy");
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        NumberFormat caseNumberFormat = NumberFormat.getIntegerInstance();
        caseNumberBox = new JFormattedTextField(caseNumberFormat);
        caseNumberBox.setColumns(20);

        this.setLayout(new MainFrameLayout());
        this.add(new JLabel("Major Release Case: "), MainFrameLayoutConstraints.NORTH);
        this.add(caseNumberBox, MainFrameLayoutConstraints.NORTH);

        this.pack();
        this.setVisible(true);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        MyApplication app = new MyApplication();
    }
}

为什么,当我 运行 这个应用程序时,我的组件(标签和文本字段)是不可见的,即使对 pack() 的调用适当地调整了 window 的大小以适合这些字段?

这就是评论员所说的..您的自定义布局并不是真正必要的。您可以直接在 MyApplication class.

中添加组件
public MyApplication() {
    ...
    setLayout(new BorderLayout(2, 1));
    ...            
    add(new JLabel("Major Release Case: "), BorderLayout.NORTH);
    add(caseNumberBox, BorderLayout.CENTER);            
    ...
}

该行为的原因是试图在布局管理器中创建组件。虽然 MainFrameLayout 为其创建的组件调用 super.addLayoutComponent(),但这些 添加到父组件本身。因此,您添加到框架的组件计数用于框架的首选大小计算,因为它被委托给 BorderLayout,它假设内容窗格包含您在 MainFrameLayout 构造函数中创建的面板,但它们永远不会被绘制为这些面板实际上并未添加到内容面板。

自定义布局管理器不是您想要实现的目标的错误工具。只需使用嵌套布局。