title: Invisible components still take up space JPanel
body: <p>I have a series of components underneath each other in a JPanel set as a GridLayout.
  I need to temporarily hide the components but <code>setVisible(false)</code> doesn't cut it, because there is still an empty gap where the components were.</p>
  
  <p>Is there a quick and easy way to do this? Or do I have to stay saving the state of the JPanel, removing the components, then restoring it?</p>
  
  <p>SSCCE:</p>
  
  <p><strong>[GridLayout2.java]</strong></p>
  
  <pre><code>import java.awt.Component;
  import java.awt.Container;
  import java.awt.Dimension;
  import java.awt.GridLayout;
  import java.awt.Insets;
  
  public class GridLayout2 extends GridLayout 
  {
    public GridLayout2() {
      this(1, 0, 0, 0);
    }
  
    public GridLayout2(int rows, int cols) {
      this(rows, cols, 0, 0);
    }
  
    public GridLayout2(int rows, int cols, int hgap, int vgap) {
      super(rows, cols, hgap, vgap);
    }
  
    public Dimension preferredLayoutSize(Container parent) {
      //System.err.println("preferredLayoutSize");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        int nrows = getRows();
        int ncols = getColumns();
        if (nrows &gt; 0) {
          ncols = (ncomponents + nrows - 1) / nrows;
        } 
        else {
          nrows = (ncomponents + ncols - 1) / ncols;
        }
        int[] w = new int[ncols];
        int[] h = new int[nrows];
        for (int i = 0; i &lt; ncomponents; i ++) {
          int r = i / ncols;
          int c = i % ncols;
          Component comp = parent.getComponent(i);
          Dimension d = comp.getPreferredSize();
          if (w[c] &lt; d.width) {
            w[c] = d.width;
          }
          if (h[r] &lt; d.height) {
            h[r] = d.height;
          }
        }
        int nw = 0;
        for (int j = 0; j &lt; ncols; j ++) {
          nw += w[j];
        }
        int nh = 0;
        for (int i = 0; i &lt; nrows; i ++) {
          nh += h[i];
        }
        return new Dimension(insets.left + insets.right + nw + (ncols-1)*getHgap(), 
            insets.top + insets.bottom + nh + (nrows-1)*getVgap());
      }
    }
  
    public Dimension minimumLayoutSize(Container parent) {
      System.err.println("minimumLayoutSize");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        int nrows = getRows();
        int ncols = getColumns();
        if (nrows &gt; 0) {
          ncols = (ncomponents + nrows - 1) / nrows;
        } 
        else {
          nrows = (ncomponents + ncols - 1) / ncols;
        }
        int[] w = new int[ncols];
        int[] h = new int[nrows];
        for (int i = 0; i &lt; ncomponents; i ++) {
          int r = i / ncols;
          int c = i % ncols;
          Component comp = parent.getComponent(i);
          Dimension d = comp.getMinimumSize();
          if (w[c] &lt; d.width) {
            w[c] = d.width;
          }
          if (h[r] &lt; d.height) {
            h[r] = d.height;
          }
        }
        int nw = 0;
        for (int j = 0; j &lt; ncols; j ++) {
          nw += w[j];
        }
        int nh = 0;
        for (int i = 0; i &lt; nrows; i ++) {
          nh += h[i];
        }
        return new Dimension(insets.left + insets.right + nw + (ncols-1)*getHgap(), 
            insets.top + insets.bottom + nh + (nrows-1)*getVgap());
      }
    }
  
    public void layoutContainer(Container parent) {
      //System.err.println("layoutContainer");
      synchronized (parent.getTreeLock()) {
        Insets insets = parent.getInsets();
        int ncomponents = parent.getComponentCount();
        int nrows = getRows();
        int ncols = getColumns();
        if (ncomponents == 0) {
          return;
        }
        if (nrows &gt; 0) {
          ncols = (ncomponents + nrows - 1) / nrows;
        } 
        else {
          nrows = (ncomponents + ncols - 1) / ncols;
        }
        int hgap = getHgap();
        int vgap = getVgap();
        // scaling factors      
        Dimension pd = preferredLayoutSize(parent);
        double sw = (1.0 * parent.getWidth()) / pd.width;
        double sh = (1.0 * parent.getHeight()) / pd.height;
        // scale
        int[] w = new int[ncols];
        int[] h = new int[nrows];
        for (int i = 0; i &lt; ncomponents; i ++) {
          int r = i / ncols;
          int c = i % ncols;
          Component comp = parent.getComponent(i);
          Dimension d = comp.getPreferredSize();
          d.width = (int) (sw * d.width);
          d.height = (int) (sh * d.height);
          if (w[c] &lt; d.width) {
            w[c] = d.width;
          }
          if (h[r] &lt; d.height) {
            h[r] = d.height;
          }
        }
        for (int c = 0, x = insets.left; c &lt; ncols; c ++) {
          for (int r = 0, y = insets.top; r &lt; nrows; r ++) {
            int i = r * ncols + c;
            if (i &lt; ncomponents) {
              parent.getComponent(i).setBounds(x, y, w[c], h[r]);
            }
            y += h[r] + vgap;
          }
          x += w[c] + hgap;
        }
      }
    }  
  }
  </code></pre>
  
  <p><strong>[SSCCE.java]</strong></p>
  
  <pre><code>import java.awt.Color;
  import javax.swing.*;
  import javax.swing.border.*;
  
  public class SSCCE extends JFrame{
  
      JPanel innerPane = new JPanel();
      JScrollPane scr  = new JScrollPane(innerPane);
  
      public static void main(String[] args) {
          new SSCCE();
      }
  
  
      public SSCCE() {
  
          setSize(400, 800);
          innerPane.setLayout(new GridLayout2(0, 1));
  
          add(scr);
  
          for (int i = 0; i &lt; 30; i++)
          {
              innerPane.add(getPane());
          }
  
          setVisible(true);
  
          try {
              Thread.sleep(2000);
          } catch (InterruptedException e) {}
  
          for (int i = 0; i &lt; 30; i++)
          {
              if (i%2==0)
                  innerPane.getComponent(i).setVisible(false);
          }
  
      }
  
  
      private JPanel getPane()
      {
          JPanel ret = new JPanel();
          JLabel lbl = new JLabel("This is a pane.");
  
          ret.add(lbl);
          ret.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
          ret.setBackground(Color.gray);
  
          return ret;
  
      }
  
  }
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/82R2A.png" alt="screenshot"></p>