Muitos JPanels dentro de um JPanel (com GridBagLayout)

Então, basicamente, se eu colocarJPanelestá dentro de umJPanel que usaGridBagLayout e restrinja o tamanho comsetPreferredSize, finalmente, atinge um ponto em que não pode conter todos eles e exibe o comportamento mostrado na figura em anexo:

Estou fazendo umaacordeão. Este é apenas um exemplo para mostrar o problema que estou tendo. Cada parte do acordeão pode ser aberta individualmente, de tamanho arbitrário e adicionada em tempo real. É fácil obter as alturas de todos os painéis individuais e compará-los com a altura total, mas quando muitos são adicionados, ele exibe o comportamento de trituração que eu mostrei. Isso também reduz as alturas, tornando muito mais difícil determinar quando a trituração ocorreu. Eu teria que armazenar em cache alturas e, de alguma forma, pré-calcular as alturas das novas peças adicionadas. O objetivo final é remover os painéis mais antigos quando um novo painel é adicionado e não há espaço suficiente para isso.

Existe uma maneira fácil de determinar qual a altura que algo teria se não estivesse restrito ou talvez uma maneira suportada de detectar quando essa crise está acontecendo (para que eu possa afinar rapidamente antes que seja pintada novamente)? Uma opção que fazGridBagLayout se comportam como alguns outros layouts e transbordamespaço do martelo em vez de compactar também funcionaria.

Código por exemplo:

import java.awt.*;
import java.awt.event.*;
import javaisms.out;
import javax.swing.*;

public class FoldDrag extends JLayeredPane {
    public TexturedPanel backingPanel = new TexturedPanel(new GridBagLayout(),"data/gui/grayerbricks.png");
    static JPanel windowbase=new JPanel();
    static JPanel restrictedpanel=new JPanel(new GridBagLayout());

    GridBagConstraints gbc = new GridBagConstraints();

    public FoldDrag() {
        JButton addpan  = new JButton("Add things");
        windowbase.add(addpan);
        windowbase.add(restrictedpanel);
        restrictedpanel.setBackground(Color.red);
        restrictedpanel.setPreferredSize(new Dimension(200,200));
        gbc.weighty=1;
        gbc.weightx=1;
        gbc.gridx=0;
        gbc.gridy=0;
        gbc.gridheight=1;
        gbc.gridwidth=1;
        gbc.fill=GridBagConstraints.HORIZONTAL;
        addpan.addActionListener(new ActionListener() {
            int number=0;
            @Override
            public void actionPerformed(ActionEvent e)
            {
                number++;
                gbc.gridy=number;
                JPanel tmppanel = new JPanel();
                tmppanel.setPreferredSize(new Dimension(100,30));
                if(number%3==0)
                    tmppanel.setBackground(Color.blue);
                if(number%3==1)
                    tmppanel.setBackground(Color.yellow);
                if(number%3==2)
                    tmppanel.setBackground(Color.green);
                restrictedpanel.add(tmppanel,gbc);
                restrictedpanel.validate();
            }
        });
        windowbase.setVisible(true);
    }
    private static void createAndShowUI() {
        JFrame frame = new JFrame("DragLabelOnLayeredPane");
        frame.getContentPane().add(windowbase);
        FoldDrag thedrag=new FoldDrag();
        windowbase.add(thedrag);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300,300));
        frame.pack();
        frame.setResizable(true);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        out.active=true;
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

Edição: Parece que não descrevi muito bem minha versão do acordeão. Aqui está umligação.

questionAnswers(3)

yourAnswerToTheQuestion