home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / FlowLayout.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  10.3 KB  |  350 lines

  1. /*
  2.  * @(#)FlowLayout.java    1.26 98/03/18
  3.  *
  4.  * Copyright 1995-1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. /**
  17.  * A flow layout arranges components in a left-to-right flow, much 
  18.  * like lines of text in a paragraph. Flow layouts are typically used 
  19.  * to arrange buttons in a panel. It will arrange
  20.  * buttons left to right until no more buttons fit on the same line.
  21.  * Each line is centered.
  22.  * <p>
  23.  * For example, the following picture shows an applet using the flow 
  24.  * layout manager (its default layout manager) to position three buttons:
  25.  * <p>
  26.  * <img src="images-awt/FlowLayout-1.gif" 
  27.  * ALT="Graphic of Layout for Three Buttons" 
  28.  * ALIGN=center HSPACE=10 VSPACE=7>
  29.  * <p>
  30.  * Here is the code for this applet: 
  31.  * <p>
  32.  * <hr><blockquote><pre>
  33.  * import java.awt.*;
  34.  * import java.applet.Applet;
  35.  * 
  36.  * public class myButtons extends Applet {
  37.  *     Button button1, button2, button3;
  38.  *     public void init() {
  39.  *         button1 = new Button("Ok");
  40.  *         button2 = new Button("Open");
  41.  *         button3 = new Button("Close");
  42.  *         add(button1);
  43.  *         add(button2);
  44.  *         add(button3);
  45.  *     }
  46.  * }
  47.  * </pre></blockquote><hr>
  48.  * <p>
  49.  * A flow layout lets each component assume its natural (preferred) size. 
  50.  *
  51.  * @version     1.26, 03/18/98
  52.  * @author     Arthur van Hoff
  53.  * @author     Sami Shaio
  54.  * @since       JDK1.0
  55.  */
  56. public class FlowLayout implements LayoutManager, java.io.Serializable {
  57.  
  58.     /**
  59.      * This value indicates that each row of components
  60.      * should be left-justified. 
  61.      */
  62.     public static final int LEFT     = 0;
  63.  
  64.     /**
  65.      * This value indicates that each row of components
  66.      * should be centered. 
  67.      */
  68.     public static final int CENTER     = 1;
  69.  
  70.     /**
  71.      * This value indicates that each row of components
  72.      * should be right-justified. 
  73.      */
  74.     public static final int RIGHT     = 2;
  75.  
  76.     int align;
  77.     int hgap;
  78.     int vgap;
  79.  
  80.     /*
  81.      * JDK 1.1 serialVersionUID 
  82.      */
  83.      private static final long serialVersionUID = -7262534875583282631L;
  84.  
  85.     /**
  86.      * Constructs a new Flow Layout with a centered alignment and a
  87.      * default 5-unit horizontal and vertical gap.
  88.      */
  89.     public FlowLayout() {
  90.     this(CENTER, 5, 5);
  91.     }
  92.  
  93.     /**
  94.      * Constructs a new Flow Layout with the specified alignment and a
  95.      * default 5-unit horizontal and vertical gap.
  96.      * The value of the alignment argument must be one of 
  97.      * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>, 
  98.      * or <code>FlowLayout.CENTER</code>.
  99.      * @param align the alignment value
  100.      */
  101.     public FlowLayout(int align) {
  102.     this(align, 5, 5);
  103.     }
  104.  
  105.     /**
  106.      * Creates a new flow layout manager with the indicated alignment 
  107.      * and the indicated horizontal and vertical gaps. 
  108.      * <p>
  109.      * The value of the alignment argument must be one of 
  110.      * <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>, 
  111.      * or <code>FlowLayout.CENTER</code>.  
  112.      * @param      align   the alignment value.
  113.      * @param      hgap    the horizontal gap between components.
  114.      * @param      vgap    the vertical gap between components.
  115.      */
  116.     public FlowLayout(int align, int hgap, int vgap) {
  117.     this.align = align;
  118.     this.hgap = hgap;
  119.     this.vgap = vgap;
  120.     }
  121.  
  122.     /**
  123.      * Gets the alignment for this layout.
  124.      * Possible values are <code>FlowLayout.LEFT</code>,  
  125.      * <code>FlowLayout.RIGHT</code>, or <code>FlowLayout.CENTER</code>.  
  126.      * @return     the alignment value for this layout.
  127.      * @see        java.awt.FlowLayout#setAlignment
  128.      * @since      JDK1.1
  129.      */
  130.     public int getAlignment() {
  131.     return align;
  132.     }
  133.     
  134.     /**
  135.      * Sets the alignment for this layout.
  136.      * Possible values are <code>FlowLayout.LEFT</code>,  
  137.      * <code>FlowLayout.RIGHT</code>, and <code>FlowLayout.CENTER</code>.  
  138.      * @param      align the alignment value.
  139.      * @see        java.awt.FlowLayout#getAlignment
  140.      * @since      JDK1.1
  141.      */
  142.     public void setAlignment(int align) {
  143.     this.align = align;
  144.     }
  145.  
  146.     /**
  147.      * Gets the horizontal gap between components.
  148.      * @return     the horizontal gap between components.
  149.      * @see        java.awt.FlowLayout#setHgap
  150.      * @since      JDK1.1
  151.      */
  152.     public int getHgap() {
  153.     return hgap;
  154.     }
  155.     
  156.     /**
  157.      * Sets the horizontal gap between components.
  158.      * @param hgap the horizontal gap between components
  159.      * @see        java.awt.FlowLayout#getHgap
  160.      * @since      JDK1.1
  161.      */
  162.     public void setHgap(int hgap) {
  163.     this.hgap = hgap;
  164.     }
  165.     
  166.     /**
  167.      * Gets the vertical gap between components.
  168.      * @return     the vertical gap between components.
  169.      * @see        java.awt.FlowLayout#setVgap
  170.      * @since      JDK1.1
  171.      */
  172.     public int getVgap() {
  173.     return vgap;
  174.     }
  175.     
  176.     /**
  177.      * Sets the vertical gap between components.
  178.      * @param vgap the vertical gap between components
  179.      * @see        java.awt.FlowLayout#getVgap
  180.      * @since      JDK1.1
  181.      */
  182.     public void setVgap(int vgap) {
  183.     this.vgap = vgap;
  184.     }
  185.  
  186.     /**
  187.      * Adds the specified component to the layout. Not used by this class.
  188.      * @param name the name of the component
  189.      * @param comp the component to be added
  190.      */
  191.     public void addLayoutComponent(String name, Component comp) {
  192.     }
  193.  
  194.     /**
  195.      * Removes the specified component from the layout. Not used by
  196.      * this class.  
  197.      * @param comp the component to remove
  198.      * @see       java.awt.Container#removeAll
  199.      */
  200.     public void removeLayoutComponent(Component comp) {
  201.     }
  202.  
  203.     /**
  204.      * Returns the preferred dimensions for this layout given the components
  205.      * in the specified target container.
  206.      * @param target the component which needs to be laid out
  207.      * @return    the preferred dimensions to lay out the 
  208.      *                    subcomponents of the specified container.
  209.      * @see Container
  210.      * @see #minimumLayoutSize
  211.      * @see       java.awt.Container#getPreferredSize
  212.      */
  213.     public Dimension preferredLayoutSize(Container target) {
  214.     Dimension dim = new Dimension(0, 0);
  215.     int nmembers = target.getComponentCount();
  216.  
  217.     for (int i = 0 ; i < nmembers ; i++) {
  218.         Component m = target.getComponent(i);
  219.         if (m.visible) {
  220.         Dimension d = m.getPreferredSize();
  221.         dim.height = Math.max(dim.height, d.height);
  222.         if (i > 0) {
  223.             dim.width += hgap;
  224.         }
  225.         dim.width += d.width;
  226.         }
  227.     }
  228.     Insets insets = target.getInsets();
  229.     dim.width += insets.left + insets.right + hgap*2;
  230.     dim.height += insets.top + insets.bottom + vgap*2;
  231.     return dim;
  232.     }
  233.  
  234.     /**
  235.      * Returns the minimum dimensions needed to layout the components
  236.      * contained in the specified target container.
  237.      * @param target the component which needs to be laid out 
  238.      * @return    the minimum dimensions to lay out the 
  239.      *                    subcomponents of the specified container.
  240.      * @see #preferredLayoutSize
  241.      * @see       java.awt.Container
  242.      * @see       java.awt.Container#doLayout
  243.      */
  244.     public Dimension minimumLayoutSize(Container target) {
  245.     Dimension dim = new Dimension(0, 0);
  246.     int nmembers = target.getComponentCount();
  247.  
  248.     for (int i = 0 ; i < nmembers ; i++) {
  249.         Component m = target.getComponent(i);
  250.         if (m.visible) {
  251.         Dimension d = m.getMinimumSize();
  252.         dim.height = Math.max(dim.height, d.height);
  253.         if (i > 0) {
  254.             dim.width += hgap;
  255.         }
  256.         dim.width += d.width;
  257.         }
  258.     }
  259.     Insets insets = target.getInsets();
  260.     dim.width += insets.left + insets.right + hgap*2;
  261.     dim.height += insets.top + insets.bottom + vgap*2;
  262.     return dim;
  263.     }
  264.  
  265.     /** 
  266.      * Centers the elements in the specified row, if there is any slack.
  267.      * @param target the component which needs to be moved
  268.      * @param x the x coordinate
  269.      * @param y the y coordinate
  270.      * @param width the width dimensions
  271.      * @param height the height dimensions
  272.      * @param rowStart the beginning of the row
  273.      * @param rowEnd the the ending of the row
  274.      */
  275.     private void moveComponents(Container target, int x, int y, int width, int height, int rowStart, int rowEnd) {
  276.     switch (align) {
  277.     case LEFT:
  278.         break;
  279.     case CENTER:
  280.         x += width / 2;
  281.         break;
  282.     case RIGHT:
  283.         x += width;
  284.         break;
  285.     }
  286.     for (int i = rowStart ; i < rowEnd ; i++) {
  287.         Component m = target.getComponent(i);
  288.         if (m.visible) {
  289.         m.setLocation(x, y + (height - m.height) / 2);
  290.         x += hgap + m.width;
  291.         }
  292.     }
  293.     }
  294.  
  295.     /**
  296.      * Lays out the container. This method lets each component take 
  297.      * its preferred size by reshaping the components in the 
  298.      * target container in order to satisfy the constraints of
  299.      * this <code>FlowLayout</code> object. 
  300.      * @param target the specified component being laid out.
  301.      * @see Container
  302.      * @see       java.awt.Container#doLayout
  303.      */
  304.     public void layoutContainer(Container target) {
  305.     Insets insets = target.getInsets();
  306.     int maxwidth = target.width - (insets.left + insets.right + hgap*2);
  307.     int nmembers = target.getComponentCount();
  308.     int x = 0, y = insets.top + vgap;
  309.     int rowh = 0, start = 0;
  310.  
  311.     for (int i = 0 ; i < nmembers ; i++) {
  312.         Component m = target.getComponent(i);
  313.         if (m.visible) {
  314.         Dimension d = m.getPreferredSize();
  315.         m.setSize(d.width, d.height);
  316.     
  317.         if ((x == 0) || ((x + d.width) <= maxwidth)) {
  318.             if (x > 0) {
  319.             x += hgap;
  320.             }
  321.             x += d.width;
  322.             rowh = Math.max(rowh, d.height);
  323.         } else {
  324.             moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, i);
  325.             x = d.width;
  326.             y += vgap + rowh;
  327.             rowh = d.height;
  328.             start = i;
  329.         }
  330.         }
  331.     }
  332.     moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, nmembers);
  333.     }
  334.     
  335.     /**
  336.      * Returns a string representation of this <code>FlowLayout</code>
  337.      * object and its values.
  338.      * @return     a string representation of this layout.
  339.      */
  340.     public String toString() {
  341.     String str = "";
  342.     switch (align) {
  343.       case LEFT:    str = ",align=left"; break;
  344.       case CENTER:  str = ",align=center"; break;
  345.       case RIGHT:   str = ",align=right"; break;
  346.     }
  347.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
  348.     }
  349. }
  350.