1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * ident        "%Z%%M% %I%     %E% SMI"
  24  *
  25  * Copyright (c) 1996-1999 by Sun Microsystems, Inc.
  26  * All rights reserved.
  27  */
  28 package com.sun.dhcpmgr.ui;
  29 
  30 import java.awt.*;
  31 
  32 /**
  33  * <CODE>VerticalButtonLayout</CODE> is used to layout buttons in a
  34  * <CODE>Panel</CODE>. It will arrange buttons top to bottom
  35  * until no more buttons fit in the same column.  Each column is
  36  * centered vertically. All buttons are set to an equal size.<P>
  37  *
  38  * While <CODE>VerticalButtonLayout</CODE> was designed for
  39  * <CODE>Buttons</CODE>, any component can be added to the layout. All
  40  * components are set to an equal size.<P>
  41  */
  42 public class VerticalButtonLayout implements LayoutManager {
  43 
  44     ALIGNMENT align;
  45     int hgap;
  46     int vgap;
  47 
  48     /**
  49      * Constructs a new <CODE>VerticalButtonLayout</CODE> with a centered
  50      * alignment.
  51      */
  52     public VerticalButtonLayout() {
  53         this(ALIGNMENT.CENTER, 5, 5);
  54     }
  55 
  56     /**
  57      * Constructs a new <CODE>VerticalButtonLayout</CODE> with the specified
  58      * alignment.
  59      * @param <VAR>align</VAR> The alignment value.
  60      * @see ALIGNMENT
  61      */
  62     public VerticalButtonLayout(ALIGNMENT align) {
  63         this(align, 5, 5);
  64     }
  65 
  66     /**
  67      * Constructs a new <CODE>VerticalButtonLayout</CODE> with the specified
  68      * alignment and gap values.
  69      * @param <VAR>align</VAR> The alignment value.
  70      * @param <VAR>hgap</VAR> The horizontal gap variable.
  71      * @param <VAR>vgap</VAR> The vertical gap variable.
  72      * @see ALIGNMENT
  73      */
  74     public VerticalButtonLayout(ALIGNMENT align, int hgap, int vgap) {
  75         this.align = align;
  76         this.hgap = hgap;
  77         this.vgap = vgap;
  78     }
  79 
  80     /**
  81      * Adds the specified component to the layout. This is not
  82      * used by this class.
  83      * @param <VAR>name</VAR>       The name of the component.
  84      * @param <VAR>comp</VAR>       The component to be added.
  85      */
  86     public void addLayoutComponent(String name, Component comp) {
  87     }
  88 
  89     /**
  90      * Removes the specified component from the layout. This
  91      * is not used by this class.  
  92      * @param <VAR>comp</VAR>       The component to remove.
  93      */
  94     public void removeLayoutComponent(Component comp) {
  95     }
  96 
  97     /**
  98      * Returns the preferred dimensions for this layout given
  99      * the components in the specified target container.
 100      * @param <VAR>target</VAR>     The component that needs to be laid out.
 101      * @see java.awt.Container
 102      * @see #minimumLayoutSize
 103      */
 104     public Dimension preferredLayoutSize(Container target) {
 105         Dimension dim = new Dimension(0, 0);
 106         int nmembers = target.getComponentCount();
 107 
 108         for (int i = 0; i < nmembers; i++) {
 109             Component m = target.getComponent(i);
 110             if (m.isVisible()) {
 111                 Dimension d = m.getPreferredSize();
 112                 dim.height = Math.max(dim.height, d.height);
 113                 dim.width = Math.max(dim.width, d.width);
 114             }
 115         }
 116         dim.height = (dim.height*nmembers) + (vgap*nmembers-1);
 117         Insets insets = target.getInsets();
 118         dim.width += insets.left + insets.right + hgap*2;
 119         dim.height += insets.top + insets.bottom + vgap*2;
 120         return dim;
 121     }
 122 
 123     /**
 124      * Returns the minimum dimensions needed to layout the components
 125      * contained in the specified target container.
 126      * @param <VAR>target</VAR>     The component that needs to be laid out 
 127      * @see #preferredLayoutSize
 128      */
 129     public Dimension minimumLayoutSize(Container target) {
 130         Dimension dim = new Dimension(0, 0);
 131         int nmembers = target.getComponentCount();
 132 
 133         for (int i = 0; i < nmembers; i++) {
 134             Component m = target.getComponent(i);
 135             if (m.isVisible()) {
 136                 Dimension d = m.getMinimumSize();
 137                 dim.height = Math.max(dim.height, d.height);
 138                 dim.width = Math.max(dim.width, d.width);
 139             }
 140         }
 141         dim.height = (dim.height*nmembers) + (vgap*nmembers-1);
 142         Insets insets = target.getInsets();
 143         dim.width += insets.left + insets.right + hgap*2;
 144         dim.height += insets.top + insets.bottom + vgap*2;
 145         return dim;
 146     }
 147 
 148     /** 
 149      * Centers the elements in the specified column, if there is any slack.
 150      * @param <VAR>target</VAR>     The component which needs to be moved.
 151      * @param <VAR>x</VAR>  The x coordinate.
 152      * @param <VAR>y</VAR>  The y coordinate.
 153      * @param <VAR>width</VAR>      The width dimensions.
 154      * @param <VAR>height</VAR>     The height dimensions.
 155      */
 156     private void moveComponents(Container target, int x, int y, int width,
 157             int height) {
 158         Dimension dim;
 159 
 160         if (align == ALIGNMENT.LEFT) {
 161             // do nothing
 162         } else if (align == ALIGNMENT.CENTER) {
 163             y += height / 2;
 164         } else if (align == ALIGNMENT.RIGHT) {
 165             y += height;
 166         }
 167         for (int i = 0; i < target.getComponentCount(); i++) {
 168             Component m = target.getComponent(i);
 169             if (m.isVisible()) {
 170                 dim = m.getSize();
 171                 m.setLocation(x + (width - dim.width) / 2, y);
 172                 y += vgap + dim.height;
 173             }
 174         }
 175     }
 176 
 177     /**
 178      * Lays out the container. This method will actually reshape the
 179      * components in the target in order to satisfy the constraints of
 180      * the <CODE>BorderLayout</CODE> object. 
 181      * @param <VAR>target</VAR>     The specified component being laid out.
 182      * @see java.awt.Container
 183      */
 184     public void layoutContainer(Container target) {
 185         Insets insets = target.getInsets();
 186         Dimension tdim = target.getSize();
 187         int maxheight = tdim.height - (insets.top + insets.bottom + vgap*2);
 188         int maxwidth = tdim.width - insets.left - insets.right;
 189         int nmembers = target.getComponentCount();
 190         Dimension dim = new Dimension(0, 0);
 191         int y = 0;
 192 
 193         for (int i = 0; i < nmembers; i++) {
 194             Component m = target.getComponent(i);
 195             if (m.isVisible()) {
 196                 Dimension d = m.getMinimumSize();
 197                 dim.height = Math.max(dim.height, d.height);
 198                 dim.width = Math.max(dim.width, d.width);
 199             }
 200         }
 201         for (int i = 0; i < nmembers; i++) {
 202             Component m = target.getComponent(i);
 203             if (m.isVisible()) {
 204                 m.setSize(dim.width, dim.height);
 205                 y += dim.height;
 206             }
 207         }
 208         moveComponents(target, insets.left, 0, maxwidth, maxheight - y);
 209     }
 210     
 211     /**
 212      * Returns the <CODE>String</CODE> representation of this
 213      * <CODE>VerticalButtonLayout</CODE>'s values.
 214      */
 215     public String toString() {
 216         String str = "";
 217         if (align == ALIGNMENT.LEFT) {
 218             str = ",align=left";
 219         } else if (align == ALIGNMENT.RIGHT) {
 220             str = ",align=right";
 221         } else if (align == ALIGNMENT.CENTER) {
 222             str = ",align=center";
 223         }
 224         return getClass().getName()
 225             + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
 226     }
 227 }