home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / FlowLayout.java < prev    next >
Text File  |  1997-10-01  |  12KB  |  370 lines

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