Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]
    1   /*
    2    * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt;
   27   
   28   /**
   29    * The <code>GridLayout</code> class is a layout manager that
   30    * lays out a container's components in a rectangular grid.
   31    * The container is divided into equal-sized rectangles,
   32    * and one component is placed in each rectangle.
   33    * For example, the following is an applet that lays out six buttons
   34    * into three rows and two columns:
   35    * <p>
   36    * <hr><blockquote>
   37    * <pre>
   38    * import java.awt.*;
   39    * import java.applet.Applet;
   40    * public class ButtonGrid extends Applet {
   41    *     public void init() {
   42    *         setLayout(new GridLayout(3,2));
   43    *         add(new Button("1"));
   44    *         add(new Button("2"));
   45    *         add(new Button("3"));
   46    *         add(new Button("4"));
   47    *         add(new Button("5"));
   48    *         add(new Button("6"));
   49    *     }
   50    * }
   51    * </pre></blockquote><hr>
   52    * <p>
   53    * If the container's <code>ComponentOrientation</code> property is horizontal
   54    * and left-to-right, the above example produces the output shown in Figure 1.
   55    * If the container's <code>ComponentOrientation</code> property is horizontal
   56    * and right-to-left, the example produces the output shown in Figure 2.
   57    * <p>
   58    * <center><table COLS=2 WIDTH=600 summary="layout">
   59    * <tr ALIGN=CENTER>
   60    * <td><img SRC="doc-files/GridLayout-1.gif"
   61    *      alt="Shows 6 buttons in rows of 2. Row 1 shows buttons 1 then 2.
   62    * Row 2 shows buttons 3 then 4. Row 3 shows buttons 5 then 6.">
   63    * </td>
   64    *
   65    * <td ALIGN=CENTER><img SRC="doc-files/GridLayout-2.gif"
   66    *                   alt="Shows 6 buttons in rows of 2. Row 1 shows buttons 2 then 1.
   67    * Row 2 shows buttons 4 then 3. Row 3 shows buttons 6 then 5.">
   68    * </td>
   69    * </tr>
   70    *
   71    * <tr ALIGN=CENTER>
   72    * <td>Figure 1: Horizontal, Left-to-Right</td>
   73    *
   74    * <td>Figure 2: Horizontal, Right-to-Left</td>
   75    * </tr>
   76    * </table></center>
   77    * <p>
   78    * When both the number of rows and the number of columns have
   79    * been set to non-zero values, either by a constructor or
   80    * by the <tt>setRows</tt> and <tt>setColumns</tt> methods, the number of
   81    * columns specified is ignored.  Instead, the number of
   82    * columns is determined from the specified number of rows
   83    * and the total number of components in the layout. So, for
   84    * example, if three rows and two columns have been specified
   85    * and nine components are added to the layout, they will
   86    * be displayed as three rows of three columns.  Specifying
   87    * the number of columns affects the layout only when the
   88    * number of rows is set to zero.
   89    *
   90    * @author  Arthur van Hoff
   91    * @since   JDK1.0
   92    */
   93   public class GridLayout implements LayoutManager, java.io.Serializable {
   94       /*
   95        * serialVersionUID
   96        */
   97       private static final long serialVersionUID = -7411804673224730901L;
   98   
   99       /**
  100        * This is the horizontal gap (in pixels) which specifies the space
  101        * between columns.  They can be changed at any time.
  102        * This should be a non-negative integer.
  103        *
  104        * @serial
  105        * @see #getHgap()
  106        * @see #setHgap(int)
  107        */
  108       int hgap;
  109       /**
  110        * This is the vertical gap (in pixels) which specifies the space
  111        * between rows.  They can be changed at any time.
  112        * This should be a non negative integer.
  113        *
  114        * @serial
  115        * @see #getVgap()
  116        * @see #setVgap(int)
  117        */
  118       int vgap;
  119       /**
  120        * This is the number of rows specified for the grid.  The number
  121        * of rows can be changed at any time.
  122        * This should be a non negative integer, where '0' means
  123        * 'any number' meaning that the number of Rows in that
  124        * dimension depends on the other dimension.
  125        *
  126        * @serial
  127        * @see #getRows()
  128        * @see #setRows(int)
  129        */
  130       int rows;
  131       /**
  132        * This is the number of columns specified for the grid.  The number
  133        * of columns can be changed at any time.
  134        * This should be a non negative integer, where '0' means
  135        * 'any number' meaning that the number of Columns in that
  136        * dimension depends on the other dimension.
  137        *
  138        * @serial
  139        * @see #getColumns()
  140        * @see #setColumns(int)
  141        */
  142       int cols;
  143   
  144       /**
  145        * Creates a grid layout with a default of one column per component,
  146        * in a single row.
  147        * @since JDK1.1
  148        */
  149       public GridLayout() {
  150           this(1, 0, 0, 0);
  151       }
  152   
  153       /**
  154        * Creates a grid layout with the specified number of rows and
  155        * columns. All components in the layout are given equal size.
  156        * <p>
  157        * One, but not both, of <code>rows</code> and <code>cols</code> can
  158        * be zero, which means that any number of objects can be placed in a
  159        * row or in a column.
  160        * @param     rows   the rows, with the value zero meaning
  161        *                   any number of rows.
  162        * @param     cols   the columns, with the value zero meaning
  163        *                   any number of columns.
  164        */
  165       public GridLayout(int rows, int cols) {
  166           this(rows, cols, 0, 0);
  167       }
  168   
  169       /**
  170        * Creates a grid layout with the specified number of rows and
  171        * columns. All components in the layout are given equal size.
  172        * <p>
  173        * In addition, the horizontal and vertical gaps are set to the
  174        * specified values. Horizontal gaps are placed between each
  175        * of the columns. Vertical gaps are placed between each of
  176        * the rows.
  177        * <p>
  178        * One, but not both, of <code>rows</code> and <code>cols</code> can
  179        * be zero, which means that any number of objects can be placed in a
  180        * row or in a column.
  181        * <p>
  182        * All <code>GridLayout</code> constructors defer to this one.
  183        * @param     rows   the rows, with the value zero meaning
  184        *                   any number of rows
  185        * @param     cols   the columns, with the value zero meaning
  186        *                   any number of columns
  187        * @param     hgap   the horizontal gap
  188        * @param     vgap   the vertical gap
  189        * @exception   IllegalArgumentException  if the value of both
  190        *                  <code>rows</code> and <code>cols</code> is
  191        *                  set to zero
  192        */
  193       public GridLayout(int rows, int cols, int hgap, int vgap) {
  194           if ((rows == 0) && (cols == 0)) {
  195               throw new IllegalArgumentException("rows and cols cannot both be zero");
  196           }
  197           this.rows = rows;
  198           this.cols = cols;
  199           this.hgap = hgap;
  200           this.vgap = vgap;
  201       }
  202   
  203       /**
  204        * Gets the number of rows in this layout.
  205        * @return    the number of rows in this layout
  206        * @since     JDK1.1
  207        */
  208       public int getRows() {
  209           return rows;
  210       }
  211   
  212       /**
  213        * Sets the number of rows in this layout to the specified value.
  214        * @param        rows   the number of rows in this layout
  215        * @exception    IllegalArgumentException  if the value of both
  216        *               <code>rows</code> and <code>cols</code> is set to zero
  217        * @since        JDK1.1
  218        */
  219       public void setRows(int rows) {
  220           if ((rows == 0) && (this.cols == 0)) {
  221               throw new IllegalArgumentException("rows and cols cannot both be zero");
  222           }
  223           this.rows = rows;
  224       }
  225   
  226       /**
  227        * Gets the number of columns in this layout.
  228        * @return     the number of columns in this layout
  229        * @since      JDK1.1
  230        */
  231       public int getColumns() {
  232           return cols;
  233       }
  234   
  235       /**
  236        * Sets the number of columns in this layout to the specified value.
  237        * Setting the number of columns has no affect on the layout
  238        * if the number of rows specified by a constructor or by
  239        * the <tt>setRows</tt> method is non-zero. In that case, the number
  240        * of columns displayed in the layout is determined by the total
  241        * number of components and the number of rows specified.
  242        * @param        cols   the number of columns in this layout
  243        * @exception    IllegalArgumentException  if the value of both
  244        *               <code>rows</code> and <code>cols</code> is set to zero
  245        * @since        JDK1.1
  246        */
  247       public void setColumns(int cols) {
  248           if ((cols == 0) && (this.rows == 0)) {
  249               throw new IllegalArgumentException("rows and cols cannot both be zero");
  250           }
  251           this.cols = cols;
  252       }
  253   
  254       /**
  255        * Gets the horizontal gap between components.
  256        * @return       the horizontal gap between components
  257        * @since        JDK1.1
  258        */
  259       public int getHgap() {
  260           return hgap;
  261       }
  262   
  263       /**
  264        * Sets the horizontal gap between components to the specified value.
  265        * @param        hgap   the horizontal gap between components
  266        * @since        JDK1.1
  267        */
  268       public void setHgap(int hgap) {
  269           this.hgap = hgap;
  270       }
  271   
  272       /**
  273        * Gets the vertical gap between components.
  274        * @return       the vertical gap between components
  275        * @since        JDK1.1
  276        */
  277       public int getVgap() {
  278           return vgap;
  279       }
  280   
  281       /**
  282        * Sets the vertical gap between components to the specified value.
  283        * @param         vgap  the vertical gap between components
  284        * @since        JDK1.1
  285        */
  286       public void setVgap(int vgap) {
  287           this.vgap = vgap;
  288       }
  289   
  290       /**
  291        * Adds the specified component with the specified name to the layout.
  292        * @param name the name of the component
  293        * @param comp the component to be added
  294        */
  295       public void addLayoutComponent(String name, Component comp) {
  296       }
  297   
  298       /**
  299        * Removes the specified component from the layout.
  300        * @param comp the component to be removed
  301        */
  302       public void removeLayoutComponent(Component comp) {
  303       }
  304   
  305       /**
  306        * Determines the preferred size of the container argument using
  307        * this grid layout.
  308        * <p>
  309        * The preferred width of a grid layout is the largest preferred
  310        * width of all of the components in the container times the number of
  311        * columns, plus the horizontal padding times the number of columns
  312        * minus one, plus the left and right insets of the target container.
  313        * <p>
  314        * The preferred height of a grid layout is the largest preferred
  315        * height of all of the components in the container times the number of
  316        * rows, plus the vertical padding times the number of rows minus one,
  317        * plus the top and bottom insets of the target container.
  318        *
  319        * @param     parent   the container in which to do the layout
  320        * @return    the preferred dimensions to lay out the
  321        *                      subcomponents of the specified container
  322        * @see       java.awt.GridLayout#minimumLayoutSize
  323        * @see       java.awt.Container#getPreferredSize()
  324        */
  325       public Dimension preferredLayoutSize(Container parent) {
  326         synchronized (parent.getTreeLock()) {
  327           Insets insets = parent.getInsets();
  328           int ncomponents = parent.getComponentCount();
  329           int nrows = rows;
  330           int ncols = cols;
  331   
  332           if (nrows > 0) {
  333               ncols = (ncomponents + nrows - 1) / nrows;
  334           } else {
  335               nrows = (ncomponents + ncols - 1) / ncols;
  336           }
  337           int w = 0;
  338           int h = 0;
  339           for (int i = 0 ; i < ncomponents ; i++) {
  340               Component comp = parent.getComponent(i);
  341               Dimension d = comp.getPreferredSize();
  342               if (w < d.width) {
  343                   w = d.width;
  344               }
  345               if (h < d.height) {
  346                   h = d.height;
  347               }
  348           }
  349           return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap,
  350                                insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
  351         }
  352       }
  353   
  354       /**
  355        * Determines the minimum size of the container argument using this
  356        * grid layout.
  357        * <p>
  358        * The minimum width of a grid layout is the largest minimum width
  359        * of all of the components in the container times the number of columns,
  360        * plus the horizontal padding times the number of columns minus one,
  361        * plus the left and right insets of the target container.
  362        * <p>
  363        * The minimum height of a grid layout is the largest minimum height
  364        * of all of the components in the container times the number of rows,
  365        * plus the vertical padding times the number of rows minus one, plus
  366        * the top and bottom insets of the target container.
  367        *
  368        * @param       parent   the container in which to do the layout
  369        * @return      the minimum dimensions needed to lay out the
  370        *                      subcomponents of the specified container
  371        * @see         java.awt.GridLayout#preferredLayoutSize
  372        * @see         java.awt.Container#doLayout
  373        */
  374       public Dimension minimumLayoutSize(Container parent) {
  375         synchronized (parent.getTreeLock()) {
  376           Insets insets = parent.getInsets();
  377           int ncomponents = parent.getComponentCount();
  378           int nrows = rows;
  379           int ncols = cols;
  380   
  381           if (nrows > 0) {
  382               ncols = (ncomponents + nrows - 1) / nrows;
  383           } else {
  384               nrows = (ncomponents + ncols - 1) / ncols;
  385           }
  386           int w = 0;
  387           int h = 0;
  388           for (int i = 0 ; i < ncomponents ; i++) {
  389               Component comp = parent.getComponent(i);
  390               Dimension d = comp.getMinimumSize();
  391               if (w < d.width) {
  392                   w = d.width;
  393               }
  394               if (h < d.height) {
  395                   h = d.height;
  396               }
  397           }
  398           return new Dimension(insets.left + insets.right + ncols*w + (ncols-1)*hgap,
  399                                insets.top + insets.bottom + nrows*h + (nrows-1)*vgap);
  400         }
  401       }
  402   
  403       /**
  404        * Lays out the specified container using this layout.
  405        * <p>
  406        * This method reshapes the components in the specified target
  407        * container in order to satisfy the constraints of the
  408        * <code>GridLayout</code> object.
  409        * <p>
  410        * The grid layout manager determines the size of individual
  411        * components by dividing the free space in the container into
  412        * equal-sized portions according to the number of rows and columns
  413        * in the layout. The container's free space equals the container's
  414        * size minus any insets and any specified horizontal or vertical
  415        * gap. All components in a grid layout are given the same size.
  416        *
  417        * @param      parent   the container in which to do the layout
  418        * @see        java.awt.Container
  419        * @see        java.awt.Container#doLayout
  420        */
  421       public void layoutContainer(Container parent) {
  422         synchronized (parent.getTreeLock()) {
  423           Insets insets = parent.getInsets();
  424           int ncomponents = parent.getComponentCount();
  425           int nrows = rows;
  426           int ncols = cols;
  427           boolean ltr = parent.getComponentOrientation().isLeftToRight();
  428   
  429           if (ncomponents == 0) {
  430               return;
  431           }
  432           if (nrows > 0) {
  433               ncols = (ncomponents + nrows - 1) / nrows;
  434           } else {
  435               nrows = (ncomponents + ncols - 1) / ncols;
  436           }
  437           // 4370316. To position components in the center we should:
  438           // 1. get an amount of extra space within Container
  439           // 2. incorporate half of that value to the left/top position
  440           // Note that we use trancating division for widthOnComponent
  441           // The reminder goes to extraWidthAvailable
  442           int totalGapsWidth = (ncols - 1) * hgap;
  443           int widthWOInsets = parent.width - (insets.left + insets.right);
  444           int widthOnComponent = (widthWOInsets - totalGapsWidth) / ncols;
  445           int extraWidthAvailable = (widthWOInsets - (widthOnComponent * ncols + totalGapsWidth)) / 2;
  446   
  447           int totalGapsHeight = (nrows - 1) * vgap;
  448           int heightWOInsets = parent.height - (insets.top + insets.bottom);
  449           int heightOnComponent = (heightWOInsets - totalGapsHeight) / nrows;
  450           int extraHeightAvailable = (heightWOInsets - (heightOnComponent * nrows + totalGapsHeight)) / 2;
  451           if (ltr) {
  452               for (int c = 0, x = insets.left + extraWidthAvailable; c < ncols ; c++, x += widthOnComponent + hgap) {
  453                   for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows ; r++, y += heightOnComponent + vgap) {
  454                       int i = r * ncols + c;
  455                       if (i < ncomponents) {
  456                           parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent);
  457                       }
  458                   }
  459               }
  460           } else {
  461               for (int c = 0, x = (parent.width - insets.right - widthOnComponent) - extraWidthAvailable; c < ncols ; c++, x -= widthOnComponent + hgap) {
  462                   for (int r = 0, y = insets.top + extraHeightAvailable; r < nrows ; r++, y += heightOnComponent + vgap) {
  463                       int i = r * ncols + c;
  464                       if (i < ncomponents) {
  465                           parent.getComponent(i).setBounds(x, y, widthOnComponent, heightOnComponent);
  466                       }
  467                   }
  468               }
  469           }
  470         }
  471       }
  472   
  473       /**
  474        * Returns the string representation of this grid layout's values.
  475        * @return     a string representation of this grid layout
  476        */
  477       public String toString() {
  478           return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap +
  479                                          ",rows=" + rows + ",cols=" + cols + "]";
  480       }
  481   }

Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]