¿Ocultar un componente de oscilación sin revalidar el diseño?

Si configuro un JFrame con algunos componentes y un administrador de diseño, que inicialmente se ve perfectamente bien, y luego debido a alguna condición (por ejemplo, haciendo clic en un botón), oculto uno de esos componentes: el administrador de diseño vuelve a mezclar todos los componentes .

Ver código de ejemplo: inicialmente aparecen 3 botones. Cuando hace clic en el botón Ocultar, el botón Ocultar está oculto, pero los dos botones exteriores se juntan. Cuando haces clic en el botón Mostrar, se separan nuevamente para hacer espacio. ¿Cómo puedo evitar que eso suceda, para que después de llamar a pack (), los componentes permanezcan donde están sin importar si luego se ocultan?

En mi código real, estoy haciendo esto con GridBagLayout, pero usé FlowLayout en el ejemplo a continuación porque es más simple y menos código, y muestra exactamente el mismo comportamiento.

Solo puedo pensar en formas desagradables de hacer esto, como usar .setEnabled (false) en lugar de .setVisible (false), y luego anular el método paintComponent () del componente para no dibujar el componente cuando está deshabilitado.

Parece el problema exactamente opuesto aquí:Ocultar un botón de Diseño en Java Swing - donde se queja de que los botones ocultoshacer todavía ocupan espacio :) Pero no hay código de muestra para mostrar que funciona de esa manera.

Muchas gracias por las sugerencias :)

Ejemplo:

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

Respuestas a la pregunta(2)

Su respuesta a la pregunta