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

  1. /*
  2.  * @(#)CardLayout.java    1.22 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.  
  15. package java.awt;
  16.  
  17. import java.util.Hashtable;
  18. import java.util.Enumeration;
  19.  
  20. /**
  21.  * A <code>CardLayout</code> object is a layout manager for a 
  22.  * container. It treats each component in the container as a card.
  23.  * Only one card is visible at a time, and the container acts as
  24.  * a stack of cards.  
  25.  * <p>
  26.  * The ordering of cards is determined by the container's own internal
  27.  * ordering of its component objects. <code>CardLayout</code> 
  28.  * defines a set of methods that allow an application to flip 
  29.  * through these cards sequentially, or to show a specified card.
  30.  * The <A HREF="#addLayoutComponent"><code>addLayoutComponent</code></A> 
  31.  * method can be used to associate a string identifier with a given card
  32.  * for fast random access.
  33.  *
  34.  * @version     1.22 03/18/98
  35.  * @author     Arthur van Hoff
  36.  * @see         java.awt.Container
  37.  * @since       JDK1.0
  38.  */
  39.  
  40. public class CardLayout implements LayoutManager2,
  41.                    java.io.Serializable {
  42.     Hashtable tab = new Hashtable();
  43.     int hgap;
  44.     int vgap;
  45.  
  46.     /**
  47.      * Creates a new card layout with gaps of size zero.
  48.      */
  49.     public CardLayout() {
  50.     this(0, 0);
  51.     }
  52.  
  53.     /**
  54.      * Creates a new card layout with the specified horizontal and 
  55.      * vertical gaps. The horizontal gaps are placed at the left and 
  56.      * right edges. The vertical gaps are placed at the top and bottom 
  57.      * edges. 
  58.      * @param     hgap   the horizontal gap.
  59.      * @param     vgap   the vertical gap.
  60.      */
  61.     public CardLayout(int hgap, int vgap) {
  62.     this.hgap = hgap;
  63.     this.vgap = vgap;
  64.     }
  65.  
  66.     /**
  67.      * Gets the horizontal gap between components.
  68.      * @return    the horizontal gap between components.
  69.      * @see       java.awt.CardLayout#setHgap(int)
  70.      * @see       java.awt.CardLayout#getVgap()
  71.      * @since     JDK1.1
  72.      */
  73.     public int getHgap() {
  74.     return hgap;
  75.     }
  76.     
  77.     /**
  78.      * Sets the horizontal gap between components.
  79.      * @param hgap the horizontal gap between components.
  80.      * @see       java.awt.CardLayout#getHgap()
  81.      * @see       java.awt.CardLayout#setVgap(int)
  82.      * @since     JDK1.1
  83.      */
  84.     public void setHgap(int hgap) {
  85.     this.hgap = hgap;
  86.     }
  87.     
  88.     /**
  89.      * Gets the vertical gap between components.
  90.      * @return the vertical gap between components.
  91.      * @see       java.awt.CardLayout#setVgap(int)
  92.      * @see       java.awt.CardLayout#getHgap()
  93.      */
  94.     public int getVgap() {
  95.     return vgap;
  96.     }
  97.     
  98.     /**
  99.      * Sets the vertical gap between components.
  100.      * @param     vgap the vertical gap between components.
  101.      * @see       java.awt.CardLayout#getVgap()
  102.      * @see       java.awt.CardLayout#setHgap(int)
  103.      * @since     JDK1.1
  104.      */
  105.     public void setVgap(int vgap) {
  106.     this.vgap = vgap;
  107.     }
  108.  
  109.     /**
  110.      * Adds the specified component to this card layout's internal
  111.      * table of names. The object specified by <code>constraints</code>  
  112.      * must be a string. The card layout stores this string as a key-value
  113.      * pair that can be used for random access to a particular card.
  114.      * By calling the <code>show</code> method, an application can  
  115.      * display the component with the specified name. 
  116.      * @param     comp          the component to be added.
  117.      * @param     constraints   a tag that identifies a particular 
  118.      *                                        card in the layout.
  119.      * @see       java.awt.CardLayout#show(java.awt.Container, java.lang.String)
  120.      * @exception  IllegalArgumentException  if the constraint is not a string.
  121.      */
  122.     public void addLayoutComponent(Component comp, Object constraints) {
  123.     if (constraints instanceof String) {
  124.         addLayoutComponent((String)constraints, comp);
  125.     } else {
  126.         throw new IllegalArgumentException("cannot add to layout: constraint must be a string");
  127.     }
  128.     }
  129.  
  130.     /**
  131.      * @deprecated   replaced by 
  132.      *      <code>addLayoutComponent(Component, Object)</code>.
  133.      */
  134.     public void addLayoutComponent(String name, Component comp) {
  135.     if (tab.size() > 0) {
  136.         comp.hide();
  137.     }
  138.     tab.put(name, comp);
  139.     }
  140.  
  141.     /**
  142.      * Removes the specified component from the layout.
  143.      * @param   comp   the component to be removed.
  144.      * @see     java.awt.Container#remove(java.awt.Component)
  145.      * @see     java.awt.Container#removeAll()
  146.      */
  147.     public void removeLayoutComponent(Component comp) {
  148.     for (Enumeration e = tab.keys() ; e.hasMoreElements() ; ) {
  149.         String key = (String)e.nextElement();
  150.         if (tab.get(key) == comp) {
  151.         tab.remove(key);
  152.         return;
  153.         }
  154.     }
  155.     }
  156.  
  157.     /** 
  158.      * Determines the preferred size of the container argument using 
  159.      * this card layout.
  160.      * @param   parent the name of the parent container.
  161.      * @return  the preferred dimensions to lay out the subcomponents 
  162.      *                of the specified container.
  163.      * @see     java.awt.Container#getPreferredSize
  164.      * @see     java.awt.CardLayout#minimumLayoutSize
  165.      */
  166.     public Dimension preferredLayoutSize(Container parent) {
  167.     Insets insets = parent.getInsets();
  168.     int ncomponents = parent.getComponentCount();
  169.     int w = 0;
  170.     int h = 0;
  171.  
  172.     for (int i = 0 ; i < ncomponents ; i++) {
  173.         Component comp = parent.getComponent(i);
  174.         Dimension d = comp.getPreferredSize();
  175.         if (d.width > w) {
  176.         w = d.width;
  177.         }
  178.         if (d.height > h) {
  179.         h = d.height;
  180.         }
  181.     }
  182.     return new Dimension(insets.left + insets.right + w + hgap*2, 
  183.                  insets.top + insets.bottom + h + vgap*2);
  184.     }
  185.  
  186.     /** 
  187.      * Calculates the minimum size for the specified panel.
  188.      * @param     parent the name of the parent container 
  189.      *                in which to do the layout.
  190.      * @return    the minimum dimensions required to lay out the 
  191.      *                subcomponents of the specified container.
  192.      * @see       java.awt.Container#doLayout
  193.      * @see       java.awt.CardLayout#preferredLayoutSize 
  194.      */
  195.     public Dimension minimumLayoutSize(Container parent) {
  196.     Insets insets = parent.getInsets();
  197.     int ncomponents = parent.getComponentCount();
  198.     int w = 0;
  199.     int h = 0;
  200.  
  201.     for (int i = 0 ; i < ncomponents ; i++) {
  202.         Component comp = parent.getComponent(i);
  203.         Dimension d = comp.getMinimumSize();
  204.         if (d.width > w) {
  205.         w = d.width;
  206.         }
  207.         if (d.height > h) {
  208.         h = d.height;
  209.         }
  210.     }
  211.     return new Dimension(insets.left + insets.right + w + hgap*2, 
  212.                  insets.top + insets.bottom + h + vgap*2);
  213.     }
  214.  
  215.     /**
  216.      * Returns the maximum dimensions for this layout given the components
  217.      * in the specified target container.
  218.      * @param target the component which needs to be laid out
  219.      * @see Container
  220.      * @see #minimumLayoutSize
  221.      * @see #preferredLayoutSize
  222.      */
  223.     public Dimension maximumLayoutSize(Container target) {
  224.     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  225.     }
  226.  
  227.     /**
  228.      * Returns the alignment along the x axis.  This specifies how
  229.      * the component would like to be aligned relative to other 
  230.      * components.  The value should be a number between 0 and 1
  231.      * where 0 represents alignment along the origin, 1 is aligned
  232.      * the furthest away from the origin, 0.5 is centered, etc.
  233.      */
  234.     public float getLayoutAlignmentX(Container parent) {
  235.     return 0.5f;
  236.     }
  237.  
  238.     /**
  239.      * Returns the alignment along the y axis.  This specifies how
  240.      * the component would like to be aligned relative to other 
  241.      * components.  The value should be a number between 0 and 1
  242.      * where 0 represents alignment along the origin, 1 is aligned
  243.      * the furthest away from the origin, 0.5 is centered, etc.
  244.      */
  245.     public float getLayoutAlignmentY(Container parent) {
  246.     return 0.5f;
  247.     }
  248.  
  249.     /**
  250.      * Invalidates the layout, indicating that if the layout manager
  251.      * has cached information it should be discarded.
  252.      */
  253.     public void invalidateLayout(Container target) {
  254.     }
  255.                       
  256.     /** 
  257.      * Lays out the specified container using this card layout. 
  258.      * <p>
  259.      * Each component in the <code>parent</code> container is reshaped 
  260.      * to be the size of the container, minus space for surrounding 
  261.      * insets, horizontal gaps, and vertical gaps. 
  262.      * 
  263.      * @param     parent the name of the parent container 
  264.      *                             in which to do the layout. 
  265.      * @see       java.awt.Container#doLayout
  266.      */
  267.     public void layoutContainer(Container parent) {
  268.     Insets insets = parent.getInsets();
  269.     int ncomponents = parent.getComponentCount();
  270.     for (int i = 0 ; i < ncomponents ; i++) {
  271.         Component comp = parent.getComponent(i);
  272.         if (comp.visible) {
  273.         comp.setBounds(hgap + insets.left, vgap + insets.top, 
  274.                    parent.width - (hgap*2 + insets.left + insets.right), 
  275.                    parent.height - (vgap*2 + insets.top + insets.bottom));
  276.         }
  277.     }
  278.     }
  279.  
  280.     /**
  281.      * Make sure that the Container really has a CardLayout installed.
  282.      * Otherwise havoc can ensue!
  283.      */
  284.     void checkLayout(Container parent) {
  285.     if (parent.getLayout() != this) {
  286.         throw new IllegalArgumentException("wrong parent for CardLayout");
  287.     }
  288.     }
  289.  
  290.     /**
  291.      * Flips to the first card of the container. 
  292.      * @param     parent   the name of the parent container 
  293.      *                          in which to do the layout.
  294.      * @see       java.awt.CardLayout#last
  295.      */
  296.     public void first(Container parent) {
  297.     synchronized (Component.LOCK) {
  298.         checkLayout(parent);
  299.         int ncomponents = parent.getComponentCount();
  300.         for (int i = 0 ; i < ncomponents ; i++) {
  301.         Component comp = parent.getComponent(i);
  302.         if (comp.visible) {
  303.             comp.hide();
  304.             comp = parent.getComponent(0);
  305.             comp.show();
  306.             parent.validate();
  307.             return;
  308.         }
  309.         }
  310.     }
  311.     }
  312.  
  313.     /**
  314.      * Flips to the next card of the specified container. If the 
  315.      * currently visible card is the last one, this method flips to the 
  316.      * first card in the layout. 
  317.      * @param     parent   the name of the parent container 
  318.      *                          in which to do the layout.
  319.      * @see       java.awt.CardLayout#previous
  320.      */
  321.     public void next(Container parent) {
  322.     synchronized (Component.LOCK) {
  323.         checkLayout(parent);
  324.         int ncomponents = parent.getComponentCount();
  325.         for (int i = 0 ; i < ncomponents ; i++) {
  326.         Component comp = parent.getComponent(i);
  327.         if (comp.visible) {
  328.             comp.hide();
  329.             comp = parent.getComponent((i + 1 < ncomponents) ? i+1 : 0);
  330.             comp.show();
  331.             parent.validate();
  332.             return;
  333.         }
  334.         }
  335.     }
  336.     }
  337.  
  338.     /**
  339.      * Flips to the previous card of the specified container. If the 
  340.      * currently visible card is the first one, this method flips to the 
  341.      * last card in the layout. 
  342.      * @param     parent   the name of the parent container 
  343.      *                          in which to do the layout.
  344.      * @see       java.awt.CardLayout#next
  345.      */
  346.     public void previous(Container parent) {
  347.     synchronized (Component.LOCK) {
  348.         checkLayout(parent);
  349.         int ncomponents = parent.getComponentCount();
  350.         for (int i = 0 ; i < ncomponents ; i++) {
  351.         Component comp = parent.getComponent(i);
  352.         if (comp.visible) {
  353.             comp.hide();
  354.             comp = parent.getComponent((i > 0) ? i-1 : ncomponents-1);
  355.             comp.show();
  356.             parent.validate();
  357.             return;
  358.         }
  359.         }
  360.     }
  361.     }
  362.  
  363.     /**
  364.      * Flips to the last card of the container. 
  365.      * @param     parent   the name of the parent container 
  366.      *                          in which to do the layout.
  367.      * @see       java.awt.CardLayout#first
  368.      */
  369.     public void last(Container parent) {
  370.     synchronized (Component.LOCK) {
  371.         checkLayout(parent);
  372.         int ncomponents = parent.getComponentCount();
  373.         for (int i = 0 ; i < ncomponents ; i++) {
  374.         Component comp = parent.getComponent(i);
  375.         if (comp.visible) {
  376.             comp.hide();
  377.             comp = parent.getComponent(ncomponents - 1);
  378.             comp.show();
  379.             parent.validate();
  380.             return;
  381.         }
  382.         }
  383.     }
  384.     }
  385.  
  386.     /**
  387.      * Flips to the component that was added to this layout with the  
  388.      * specified <code>name</code>, using <code>addLayoutComponent</code>.  
  389.      * If no such component exists, then nothing happens. 
  390.      * @param     parent   the name of the parent container 
  391.      *                     in which to do the layout.
  392.      * @param     name     the component name.
  393.      * @see       java.awt.CardLayout#addLayoutComponent(java.awt.Component, java.lang.Object)
  394.      */
  395.     public void show(Container parent, String name) {
  396.     synchronized (Component.LOCK) {
  397.         checkLayout(parent);
  398.         Component next = (Component)tab.get(name);
  399.         if ((next != null) && !next.visible){
  400.         int ncomponents = parent.getComponentCount();
  401.         for (int i = 0 ; i < ncomponents ; i++) {
  402.             Component comp = parent.getComponent(i);
  403.             if (comp.visible) {
  404.             comp.hide();
  405.             break;
  406.             }
  407.         }
  408.         next.show();
  409.         parent.validate();
  410.         }
  411.     }
  412.     }
  413.     
  414.     /**
  415.      * Returns a string representation of the state of this card layout.
  416.      * @return    a string representation of this card layout.
  417.      */
  418.     public String toString() {
  419.     return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
  420.     }
  421. }
  422.