Demasiados JPanels dentro de un JPanel (con GridBagLayout)

Así que básicamente si pongoJPanels dentro de unJPanel que usaGridBagLayout y restrinjo el tamaño consetPreferredSize, eventualmente llega a un punto donde no puede contenerlos a todos, y exhibe el comportamiento que se muestra en la imagen adjunta:

Estoy haciendo unacordeón. Este es solo un ejemplo para mostrar el problema que estoy teniendo. Cada parte del acordeón puede abrirse individualmente y son de tamaño arbitrario y se agregan sobre la marcha. Es bastante fácil obtener las alturas de todos los paneles individuales y compararlos con la altura total, pero cuando se agregan demasiados, muestra el comportamiento crujiente que he mostrado. Esto también reduce las alturas, por lo que es mucho más difícil determinar cuándo se produjo el crujido. Tendría que almacenar en caché las alturas y de alguna manera precalcular las alturas de las nuevas piezas que se agregan. El objetivo final es eliminar los paneles más antiguos cuando se agrega un nuevo panel y no hay suficiente espacio para ello.

¿Hay una manera fácil de determinar qué altura tendría algo si no estuviera restringido, o tal vez una forma compatible de detectar cuándo está ocurriendo ese crujido (para que pueda diluirlo rápidamente antes de que se vuelva a pintar)? Una opción que haceGridBagLayout comportarse como algunos otros diseños y desbordar enhammerspace en lugar de comprimir funcionaría también.

Código por ejemplo:

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();
            }
        });
    }
}

EDITAR: Parece que no describí muy bien mi versión del acordeón. Aquí está unenlazar.

Respuestas a la pregunta(3)

Su respuesta a la pregunta