Слишком много JPanels внутри JPanel (с GridBagLayout)

Так что в основном, если я поставлюJPanelс внутриJPanel который используетGridBagLayout и я ограничиваю размер сsetPreferredSizeв конце концов он достигает точки, в которой он не может удержать их всех, и демонстрирует поведение, показанное на прилагаемой картинке:

Я делаюаккордеон, Это всего лишь пример, демонстрирующий мою проблему. Каждая часть аккордеона может открываться индивидуально, и они имеют произвольный размер и добавляются на лету. Достаточно просто получить высоту всех отдельных панелей и сравнить их с общей высотой, но когда добавлено слишком много, это демонстрирует хрустящее поведение, которое я показал. Это также уменьшает высоту, поэтому намного сложнее определить, когда произошло сжатие. Я должен был бы кэшировать высоты и каким-то образом предварительно вычислять высоты добавляемых новых частей. Конечная цель состоит в том, чтобы удалить старые панели, когда добавляется новая панель, и для нее недостаточно места.

Есть ли простой способ определить, какой высоты будет что-то, если он не ограничен, или, может быть, есть поддерживаемый способ определения того, когда происходит такой хруст (так что я могу быстро уменьшить его до того, как он снова будет окрашен)? Опция, которая делаетGridBagLayout вести себя как другие макеты и перетекать вhammerspace вместо сжатия тоже будет работать.

Код например:

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

РЕДАКТИРОВАТЬ: Кажется, я не очень хорошо описал мою версию аккордеона. Вотссылка на сайт.

Ответы на вопрос(3)

Ваш ответ на вопрос