title: Hide a swing component without revalidating the layout?
body: <p>If I set up a JFrame with some components and a layout manager, which initially looks perfectly fine, and then later due to some condition (say, clicking a button) I hide one of those components - the layout manager shuffles all the components around again.</p>
  
  <p>See example code - initially 3 buttons appear.  When you click the Hide button, the Hide button is hidden - but the two outer buttons then squash together.  When you click the show button, they move apart again to make space.  How can I stop that from happening, so that after I call pack (), components stay where they are no matter if they later become hidden?</p>
  
  <p>In my real code I'm doing this with GridBagLayout, but used FlowLayout in the example below because its simpler and less code, and shows exactly the same behaviour.</p>
  
  <p>I can only think of nasty ways of doing this, like using .setEnabled (false) instead of .setVisible (false), and then overriding the component's paintComponent () method to not draw the component when it is disabled.</p>
  
  <p>It seems the exact opposite problem to here - <a href="https://stackoverflow.com/questions/1917365/hide-a-button-from-layout-in-java-swing">Hide a button from Layout in Java Swing</a> - where is complaining that hidden buttons <em>do</em> still take up space :) But there's no sample code there to show it working in that way.</p>
  
  <p>Many thanks for any suggestions :)</p>
  
  <p>Example:</p>
  
  <pre><code>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 ();
              }
          });
      }
  }
  </code></pre>