Скрыть компонент свинга без повторной проверки макета?

Если я установлю JFrame с некоторыми компонентами и менеджером макета, который изначально выглядит отлично, а затем из-за какого-то условия (скажем, нажав кнопку), позже я скрываю один из этих компонентов - менеджер компоновки снова перемешивает все компоненты. ,

Смотрите пример кода - изначально появляются 3 кнопки. Когда вы нажимаете кнопку «Скрыть», кнопка «Скрыть» скрывается, но две внешние кнопки сжимаются вместе. Когда вы нажимаете кнопку показа, они снова раздвигаются, чтобы освободить место. Как я могу предотвратить это, чтобы после вызова pack () компоненты оставались там, где они есть, независимо от того, будут ли они позже скрыты?

В моем реальном коде я делаю это с GridBagLayout, но использовал FlowLayout в приведенном ниже примере, потому что это более простой и менее кодовый код, и демонстрирует точно такое же поведение.

Я могу думать только о неприятных способах сделать это, например, использовать .setEnabled (false) вместо .setVisible (false), а затем переопределить метод paintComponent () компонента, чтобы не рисовать компонент, когда он отключен.

Кажется, проблема прямо противоположна здесь -Скрыть кнопку из Layout в Java Swing - где жалуется, что скрытые кнопкиделать все еще занимают место :) Но там нет примера кода, чтобы показать, как он работает таким образом.

Большое спасибо за любые предложения :)

Пример:

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RevalidateWhenSetChildInvisibleExample
{
    private JButton button1;
    private JButton button2;
    private JButton button3;

    public void run ()
    {
        // Set up action
        Action hideButtonAction = new AbstractAction ()
        {
            @Override
            public void actionPerformed (ActionEvent e)
            {
                button2.setVisible (false);
            }
        };
        hideButtonAction.putValue (Action.NAME, "Hide");

        Action showButtonAction = new AbstractAction ()
        {
            @Override
            public void actionPerformed (ActionEvent e)
            {
                button2.setVisible (true);
            }
        };
        showButtonAction.putValue (Action.NAME, "Show");

        // Set up buttons
        button1 = new JButton ("Dummy");
        button2 = new JButton (hideButtonAction);
        button3 = new JButton (showButtonAction);

        // Set up content pane
        JPanel contentPane = new JPanel ();
        contentPane.setLayout (new FlowLayout ());
        contentPane.add (button1);
        contentPane.add (button2);
        contentPane.add (button3);

        // Set up frame
        JFrame frame = new JFrame ();
        frame.setContentPane (contentPane);
        frame.pack ();
        frame.setVisible (true);
    }

    public static void main (String args [])
    {
        SwingUtilities.invokeLater (new Runnable ()
        {
            public void run ()
            {
                new RevalidateWhenSetChildInvisibleExample ().run ();
            }
        });
    }
}

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

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