Mega Code Archive

 
Categories / Java / Swing JFC
 

Place components at exact locations (x, y, width, height) and then determine how they behave when the window containing them (th

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: // //  <title>fun1 example</title> //  <applet code="fun1.class" width=400 height=300> </applet> // // 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);   } }