import java.awt.*;

/** The problem and how this class solves it --
 * A common "button box" implementation is a Panel with a FlowLayout,
 * placed as North or South in another Panel with BorderLayout.
 * It does not work properly for more than three or four buttons:
 * North & South Borders holding a FlowLayout are one row high,
 * the FlowLayout wraps but doesn't get needed space,
 * I think just because it doesn't request it,
 * so Children that wrap are not visible.

 * This sounds more like a bug than a feature,
 * because there is no warning but some elements are not shown.
 * It has been asked (but not Frequently) in the newsgroups.
 
 * More evidence it is a bug not feature:
 * Grid or TextArea (and other things) work properly in Borders,
 * because they do request their needed space.
 * North or South claims needed vertical space,
 * takes all horizontal as given.

 * This extension requests height for wrapped rows,
 * so all Children are visible as expected.
 * We call the deprecated &quot;insets ()&quot; form for portability.

 * First request --anything-- nonzero to not be left out,
 * an initial request for zero space could get us optimized away.
 * Get full width if North or South,
 * or full height if West or East,
 * less any North and South.

 * Then compute based on the layout,
 * actual Location and Size assigned each Component,
 * after provoking another validate.
 * Here is one way for the BorderLayout Panel to do that --

 *  public void show () {
 *      super.show ();
 *      NorthFP.invalidate ();
 *      Center.invalidate ();
 *      SouthFP.invalidate ();
 *      validate ();
 *  }

 * Caution!
 * If the BorderLayout Panel happens to be a modal Dialog,
 * it cannot rely on the show () method this way,
 * because it gets called very late in the game.
 * Do pack before and after instead,
 * at the very end of the constructor code.
 * This works for a modal Dialog --

 *  public myClass () {
 *    ...
 *    pack ();
 *    SouthFP.invalidate ();
 *    validate ();
 *    pack ();
 *  }
 * @author Morris Hirsch IPD
 */

public class WrapLayout extends FlowLayout {

   private int Hgap = 3, Vgap = 3;

/** Although we must declare them here,
 * all constructors defer to the super class,
 * likewise all get/set parameter methods,
 * and add / remove methods,
 * and layout proper. */

    WrapLayout () {
	super ();
    }

    WrapLayout (int fo) {
	super (fo);
    }

    WrapLayout (int fo, int ho, int vo) {
	super (fo, ho, vo);
	Hgap = ho;
	Vgap = vo;
    }

/** Figure out what we **REALLY** need with possible wrap-arounds. */

    public Dimension preferredLayoutSize (Container con) {

      super.preferredLayoutSize (con);

      //Insets insets = con.getInsets ();
      Insets insets = con.insets ();

      int Ibottom = insets.bottom;
      int Iright = insets.right;

      // Hgap = getHgap ();
      // Vgap = getVgap ();

/* Find furthest extent of width and height */

      int ww = 0, hh = 0;
      Component [] cc = con.getComponents ();

      for (int ii = 0; ii < cc.length; ii++) {
	  //Point cl = cc[ii].getLocation ();
	  Point cl = cc[ii].location ();

	  //Dimension cs = cc[ii].getSize ();
	  Dimension cs = cc[ii].size ();

	  if (ww < cl.x + cs.width)
	      ww = cl.x + cs.width;

	  if (hh < cl.y + cs.height)
	      hh = cl.y + cs.height;
      }

/* The LM has already allowed for top and left insets,
 * and for H and V gaps between components.
 * We add allowance for bottom and right insets,
 * and additional H and V gaps beyond furthest components.
 * This comes out looking right. */

      ww += Iright;
      ww += Hgap;
      hh += Ibottom;
      hh += Vgap;

/* Never ever ask for zero.  An optimizer might get you. */

      if (ww < 20)
	  ww = 20;

      if (hh < 20)
	  hh = 20;

      return new Dimension (ww, hh);
    }

/** Now that layout has been done, this is really needed. */

    public Dimension minimumLayoutSize (Container con) {
	return preferredLayoutSize (con);
    }

}
/* <IMG SRC="/cgi-bin/counter">*/
