Swing JFC Java

import java.awt.*;
import java.util.*;
/*
 * @(#)FunLayout.java   1.0  96/10/12  Eric Swildens  Copyright (c) 1996
 *
 * Permission to use, copy, modify, and distribute this software
 * for any purpose is hereby granted provided that this copyright
 * notice appears in all copies.
 *
 * NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE ARE GIVEN, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 */
public class FunLayout implements LayoutManager
{
// Using this layout manager, you can place components at exact
// locations (x, y, width, height) and then determine how they
// behave when the window containing them (their parent) is resized.
//
// sample use:
//
// fun1.html:
//
//  fun1 example
//   
//
// fun1.java:
//
//  import java.applet.Applet;
//  import java.awt.*;
//
//  public class fun1 extends Applet
//  {
//  public void init()
//    {
//    FunLayout layout = new FunLayout();
//    setLayout(layout);
//
//    setBackground(Color.lightGray);
//
//    Button rightButton1 = new Button("Button1");
//    rightButton1.reshape(300, 5, 90, 20);
//    add(rightButton1);
//    layout.movesRight(rightButton1);
//
//    Button rightButton2 = new Button("Button 2");
//    rightButton2.reshape(200, 5, 90, 20);
//    add(rightButton2);
//    layout.movesRight(rightButton2);
//
//    Panel midPanel = new Panel();
//    midPanel.reshape(5, 40, 390, 200);
//    midPanel.setBackground(Color.blue);
//    layout.widthChanges(midPanel);
//    layout.heightChanges(midPanel);
//    add(midPanel);
//
//    Panel statusBar = new Panel();
//    statusBar.reshape(5, 245, 390, 20);
//    statusBar.setBackground(Color.black);
//    layout.movesDown(statusBar);
//    layout.widthChanges(statusBar);
//    add(statusBar);
//    }
//  }
//
// The above code creates an applet containing 2 buttons, a center panel
// and a status panel.  The two buttons are placed next to each other
// in the upper right.  When the window is sized wider, the buttons
// will move to the right to stick near the edge of the window.
//
// The midPanel is placed in the center and when the window is sized
// larger (in both dimensions), the panel will grow wider and taller.
//
// The statusBar is placed on the bottom and sticks to the bottom of
// the panel when it is sized larger or smaller in height (it moves
// down if the window it is contained in is sized to a larger height).
// It will grow wider if the window it is contained in is sized wider.
//
// The advantage of the FunLayout is that you place components where you
// want them to appear (best when using an interface builder) and still
// have control over what happens during sizing.
//
// This is the default layout mechanism many interface systems use, such
// as Netscape's IFC.  In fact, if you use this layout manager, you will
// find porting your code to Netscape's IFC much easier, as the layout
// container here is very similar to Netscape's IFC layout mechanism.
//
// There are only 4 methods which determine how components are resized
//
//   layout.movesRight(comp);
//   layout.movesDown(comp);
//   layout.widthChanges(comp);
//   layout.heightChanges(comp);
//
// When you determine which to choose, you should ask "What should the
// component do when the window is sized larger?"
//
// If you don't call any of the above methods for a component, it will
// simply stay at its current location.
//
// It's more Fun than a Bag of layouts :-)
//
private Hashtable _moves;
private Hashtable _negSized;
private Dimension _prevContainerSize;
private final static int MOVES_RIGHT     =  2;
private final static int MOVES_DOWN      =  4;
private final static int HEIGHT_CHANGES  =  8;
private final static int WIDTH_CHANGES   = 16;
public FunLayout()
  {
  _moves = new Hashtable();
  _negSized = new Hashtable();
  }
private int _getMove(Component comp)
  {
  if (!_moves.containsKey(comp))
    return 0;
  return ((Integer)_moves.get(comp)).intValue();
  }
//
// private methods
//
private void _setMove(Component comp, int move)
  {
  if (_moves.containsKey(comp))
    {
    move |= ((Integer)_moves.get(comp)).intValue();
    _moves.remove(comp);
    }
  _moves.put(comp, new Integer(move));
  }
//
// LayoutManager implementation
//
public void addLayoutComponent(String name, Component c)
  {
  }
/**
  * When the window containing the given component is stretched to a
  * larger height, the given component will grow taller (and shorter
  * when the window is shortened).
  * @param comp the target Component
  */
public void heightChanges(Component comp)
  {
  if ((_getMove(comp) & MOVES_DOWN) > 0)
    System.out.println(getClass() + ":layout conflict for " + comp);
  _setMove(comp, HEIGHT_CHANGES);
  }
public void layoutContainer(Container con)
  {
  int i, count, deltax, deltay, move;
  Dimension conSize;
  Rectangle rect;
  Component comp;
  conSize = con.getSize();
  if (_prevContainerSize == null)
    {
    _prevContainerSize = conSize;
    return;
    }
  deltax = conSize.width - _prevContainerSize.width;
  deltay = conSize.height - _prevContainerSize.height;
  _prevContainerSize = conSize;
  count = con.countComponents();
  for (i = 0; i < count; i++)
    {
    comp = con.getComponent(i);
    if (!comp.isVisible())
      continue;
    move = _getMove(comp);
    if (move == 0)
      continue;
    rect = comp.getBounds();
    if (_negSized.containsKey(comp))
      {
      // the component is really at a negative size
      rect = (Rectangle)_negSized.get(comp);
      _negSized.remove(comp);
      }
    if ((move & MOVES_RIGHT) > 0)
      rect.x += deltax;
    else if ((move & WIDTH_CHANGES) > 0)
      rect.width += deltax;
    if ((move & MOVES_DOWN) > 0)
      rect.y += deltay;
    else if ((move & HEIGHT_CHANGES) > 0)
      rect.height += deltay;
    // if a components size becomes negative, we track it since the AWT
    // does not allow components to have a size < (0, 0)
    if (rect.width < 0 || rect.height < 0)
      _negSized.put(comp, rect);
    comp.setBounds(rect.x, rect.y, rect.width, rect.height);
    }
  }
public Dimension minimumLayoutSize(Container target)
  {
  return new Dimension(10, 10);
  }
/**
  * When the window containing the given component is stretched to a
  * larger height, the given component will move down (and up
  * when the window is shortened).
  * @param comp the target Component
  */
public void movesDown(Component comp)
  {
  if ((_getMove(comp) & HEIGHT_CHANGES) > 0)
    System.out.println(getClass() + ":layout conflict for " + comp);
  _setMove(comp, MOVES_DOWN);
  }
//
// public methods
//
/**
  * When the window containing the given component is widened, the
  * component will move right (and left when the window is shrunk).
  * @param comp the target Component
  */
public void movesRight(Component comp)
  {
  if ((_getMove(comp) & WIDTH_CHANGES) > 0)
    System.out.println(getClass() + ":layout conflict for " + comp);
  _setMove(comp, MOVES_RIGHT);
  }
public Dimension preferredLayoutSize(Container con)
  {
  Component comp;
  Rectangle rect;
  int i, count;
  Dimension d;
  d = new Dimension(0, 0);
  count = con.countComponents();
  for (i = 0; i < count; i++)
    {
    comp = con.getComponent(i);
    if (!comp.isVisible())
      continue;
    rect = comp.getBounds();
    if (d.width < rect.x + rect.width)
      d.width = rect.x + rect.width;
    if (d.height < rect.y + rect.height)
      d.height = rect.y + rect.height;
    }
  return d;
  }
public void removeLayoutComponent(Component c)
  {
  if (_negSized.containsKey(c))
    _negSized.remove(c);
  }
/**
  * When the window containing the given component is widened, the
  * component will grow wider (and smaller when the window is shrunk).
  * @param comp the target Component
  */
public void widthChanges(Component comp)
  {
  if ((_getMove(comp) & MOVES_RIGHT) > 0)
    System.out.println(getClass() + ":layout conflict for " + comp);
  _setMove(comp, WIDTH_CHANGES);
  }
}