    001/* ========================================================================
    002 * JCommon : a free general purpose class library for the Java(tm) platform
    003 * ========================================================================
    004 *
    005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006 *
    007 * Project Info:  http://www.jfree.org/jcommon/index.html
    008 *
    009 * This library is free software; you can redistribute it and/or modify it
    010 * under the terms of the GNU Lesser General Public License as published by
    011 * the Free Software Foundation; either version 2.1 of the License, or
    012 * (at your option) any later version.
    013 *
    014 * This library is distributed in the hope that it will be useful, but
    015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017 * License for more details.
    018 *
    019 * You should have received a copy of the GNU Lesser General Public
    020 * License along with this library; if not, write to the Free Software
    021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022 * USA.
    023 *
    024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025 * in the United States and other countries.]
    026 *
    027 * -----------------
    028 * FormatLayout.java
    029 * -----------------
    030 * (C) Copyright 2000-2005, by Object Refinery Limited.
    031 *
    032 * Original Author:  David Gilbert (for Object Refinery Limited);
    033 * Contributor(s):   -;
    034 *
    035 * $Id: FormatLayout.java,v 1.4 2005/10/18 13:16:50 mungady Exp $
    036 *
    037 * Changes (from 26-Oct-2001)
    038 * --------------------------
    039 * 26-Oct-2001 : Changed package to com.jrefinery.layout.* (DG);
    040 * 26-Jun-2002 : Removed redundant code (DG);
    041 * 10-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    042 *
    043 */
    044
    045package org.jfree.layout;
    046
    047import java.awt.Component;
    048import java.awt.Container;
    049import java.awt.Dimension;
    050import java.awt.Insets;
    051import java.awt.LayoutManager;
    052import java.io.Serializable;
    053
    054/**
    055 * A layout manager that spaces components over six columns in seven different
    056 * formats.
    057 *
    058 * @author David Gilbert
    059 */
    060public class FormatLayout implements LayoutManager, Serializable {
    061
    062    /** For serialization. */
    063    private static final long serialVersionUID = 2866692886323930722L;
    064
    065    /** A useful constant representing layout format 1. */
    066    public static final int C = 1;
    067
    068    /** A useful constant representing layout format 2. */
    069    public static final int LC = 2;
    070
    071    /** A useful constant representing layout format 3. */
    072    public static final int LCB = 3;
    073
    074    /** A useful constant representing layout format 4. */
    075    public static final int LCLC = 4;
    076
    077    /** A useful constant representing layout format 5. */
    078    public static final int LCLCB = 5;
    079
    080    /** A useful constant representing layout format 6. */
    081    public static final int LCBLC = 6;
    082
    083    /** A useful constant representing layout format 7. */
    084    public static final int LCBLCB = 7;
    085
    086    /** The layout format for each row. */
    087    private int[] rowFormats;
    088
    089    /** The gap between the rows. */
    090    private int rowGap;
    091
    092    /**
    093     * The gaps between the columns (gap[0] is the gap following column zero).
    094     */
    095    private int[] columnGaps;
    096
    097    /** Working array for recording the height of each row. */
    098    private int[] rowHeights;
    099
    100    /** The total height of the layout. */
    101    private int totalHeight;
    102
    103    /** Working array for recording the width of each column. */
    104    private int[] columnWidths;
    105
    106    /** The total width of the layout. */
    107    private int totalWidth;
    108
    109    /** Combined width of columns 1 and 2. */
    110    private int columns1and2Width;
    111
    112    /** Combined width of columns 4 and 5. */
    113    private int columns4and5Width;
    114
    115    /** Combined width of columns 1 to 4. */
    116    private int columns1to4Width;
    117
    118    /** Combined width of columns 1 to 5. */
    119    private int columns1to5Width;
    120
    121    /** Combined width of columns 0 to 5. */
    122    private int columns0to5Width;
    123
    124    /**
    125     * Constructs a new layout manager that can be used to create input forms.
    126     * The layout manager works by arranging components in rows using six
    127     * columns (some components will use more than one column).
    128     * <P>
    129     * Any component can be added, but I think of them in terms of Labels,
    130     * Components, and Buttons.
    131     * The formats available are:  C, LC, LCB, LCLC, LCLCB, LCBLC or LCBLCB.
    132     * <table>
    133     * <tr>
    134     * <td>C</td>
    135     * <td>1 component in this row (spread across all six columns).</td>
    136     * </tr>
    137     * <tr>
    138     * <td>LC</td>
    139     * <td>2 components, a label in the 1st column, and a component using the
    140     *      remaining 5 columns).</td>
    141     * </tr>
    142     * <tr>
    143     * <td>LCB</td>
    144     * <td>3 components, a label in the 1st column, a component spread across
    145     *      the next 4, and a button in the last column.</td>
    146     * </tr>
    147     * <tr>
    148     * <td>LCLC</td>
    149     * <td>4 components, a label in column 1, a component in 2-3, a label in
    150     *       4 and a component in 5-6.</td>
    151     * </tr>
    152     * <tr>
    153     * <td>LCLCB</td>
    154     * <td>5 components, a label in column 1, a component in 2-3, a label
    155     *      in 4, a component in 5 and a button in 6.</td>
    156     * </tr>
    157     * <tr>
    158     * <td>LCBLC</td>
    159     * <td>5 components, a label in column 1, a component in 2, a button in 3,
    160     *  a label in 4, a component in 5-6.</td>
    161     * </tr>
    162     * <tr>
    163     * <td>LCBLCB</td>
    164     * <td>6 components, one in each column.</td>
    165     * </tr>
    166     * </table>
    167     * <P>
    168     * Columns 1 and 4 expand to accommodate the widest label, and 3 and 6 to
    169     * accommodate the widest button.
    170     * <P>
    171     * Each row will contain the number of components indicated by the format.
    172     * Be sure to specify enough row formats to cover all the components you
    173     * add to the layout.
    174     *
    175     * @param rowCount  the number of rows.
    176     * @param rowFormats  the row formats.
    177     */
    178    public FormatLayout(final int rowCount, final int[] rowFormats) {
    179
    180        this.rowFormats = rowFormats;
    181        this.rowGap = 2;
    182        this.columnGaps = new int[5];
    183        this.columnGaps[0] = 10;
    184        this.columnGaps[1] = 5;
    185        this.columnGaps[2] = 5;
    186        this.columnGaps[3] = 10;
    187        this.columnGaps[4] = 5;
    188
    189        // working structures...
    190        this.rowHeights = new int[rowCount];
    191        this.columnWidths = new int[6];
    192    }
    193
    194    /**
    195     * Returns the preferred size of the component using this layout manager.
    196     *
    197     * @param parent  the parent.
    198     *
    199     * @return the preferred size of the component.
    200     */
    201    public Dimension preferredLayoutSize(final Container parent) {
    202
    203        Component c0, c1, c2, c3, c4, c5;
    204
    205        synchronized (parent.getTreeLock()) {
    206            final Insets insets = parent.getInsets();
    207            int componentIndex = 0;
    208            final int rowCount = this.rowHeights.length;
    209            for (int i = 0; i < this.columnWidths.length; i++) {
    210                this.columnWidths[i] = 0;
    211            }
    212            this.columns1and2Width = 0;
    213            this.columns4and5Width = 0;
    214            this.columns1to4Width = 0;
    215            this.columns1to5Width = 0;
    216            this.columns0to5Width = 0;
    217
    218            this.totalHeight = 0;
    219            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    220            final int format
    221                = this.rowFormats[rowIndex % this.rowFormats.length];
    222                switch (format) {
    223                    case FormatLayout.C:
    224                        c0 = parent.getComponent(componentIndex);
    225                        updateC(rowIndex, c0.getPreferredSize());
    226                        componentIndex = componentIndex + 1;
    227                        break;
    228                    case FormatLayout.LC:
    229                        c0 = parent.getComponent(componentIndex);
    230                        c1 = parent.getComponent(componentIndex + 1);
    231                        updateLC(rowIndex, c0.getPreferredSize(),
    232                                c1.getPreferredSize());
    233                        componentIndex = componentIndex + 2;
    234                        break;
    235                    case FormatLayout.LCB:
    236                        c0 = parent.getComponent(componentIndex);
    237                        c1 = parent.getComponent(componentIndex + 1);
    238                        c2 = parent.getComponent(componentIndex + 2);
    239                        updateLCB(rowIndex,
    240                                  c0.getPreferredSize(),
    241                                  c1.getPreferredSize(),
    242                                  c2.getPreferredSize());
    243                        componentIndex = componentIndex + 3;
    244                        break;
    245                    case FormatLayout.LCLC:
    246                        c0 = parent.getComponent(componentIndex);
    247                        c1 = parent.getComponent(componentIndex + 1);
    248                        c2 = parent.getComponent(componentIndex + 2);
    249                        c3 = parent.getComponent(componentIndex + 3);
    250                        updateLCLC(rowIndex,
    251                                   c0.getPreferredSize(),
    252                                   c1.getPreferredSize(),
    253                                   c2.getPreferredSize(),
    254                                   c3.getPreferredSize());
    255                        componentIndex = componentIndex + 4;
    256                        break;
    257                    case FormatLayout.LCBLC:
    258                        c0 = parent.getComponent(componentIndex);
    259                        c1 = parent.getComponent(componentIndex + 1);
    260                        c2 = parent.getComponent(componentIndex + 2);
    261                        c3 = parent.getComponent(componentIndex + 3);
    262                        c4 = parent.getComponent(componentIndex + 4);
    263                        updateLCBLC(rowIndex,
    264                                    c0.getPreferredSize(),
    265                                    c1.getPreferredSize(),
    266                                    c2.getPreferredSize(),
    267                                    c3.getPreferredSize(),
    268                                    c4.getPreferredSize());
    269                        componentIndex = componentIndex + 5;
    270                        break;
    271                    case FormatLayout.LCLCB:
    272                        c0 = parent.getComponent(componentIndex);
    273                        c1 = parent.getComponent(componentIndex + 1);
    274                        c2 = parent.getComponent(componentIndex + 2);
    275                        c3 = parent.getComponent(componentIndex + 3);
    276                        c4 = parent.getComponent(componentIndex + 4);
    277                        updateLCLCB(rowIndex,
    278                                    c0.getPreferredSize(),
    279                                    c1.getPreferredSize(),
    280                                    c2.getPreferredSize(),
    281                                    c3.getPreferredSize(),
    282                                    c4.getPreferredSize());
    283                        componentIndex = componentIndex + 5;
    284                        break;
    285                    case FormatLayout.LCBLCB:
    286                        c0 = parent.getComponent(componentIndex);
    287                        c1 = parent.getComponent(componentIndex + 1);
    288                        c2 = parent.getComponent(componentIndex + 2);
    289                        c3 = parent.getComponent(componentIndex + 3);
    290                        c4 = parent.getComponent(componentIndex + 4);
    291                        c5 = parent.getComponent(componentIndex + 5);
    292                        updateLCBLCB(rowIndex,
    293                                     c0.getPreferredSize(),
    294                                     c1.getPreferredSize(),
    295                                     c2.getPreferredSize(),
    296                                     c3.getPreferredSize(),
    297                                     c4.getPreferredSize(),
    298                                     c5.getPreferredSize());
    299                        componentIndex = componentIndex + 6;
    300                        break;
    301                }
    302            }
    303            complete();
    304            return new Dimension(this.totalWidth + insets.left + insets.right,
    305                    this.totalHeight + (rowCount - 1) * this.rowGap
    306                                 + insets.top + insets.bottom);
    307        }
    308    }
    309
    310    /**
    311     * Returns the minimum size of the component using this layout manager.
    312     *
    313     * @param parent  the parent.
    314     *
    315     * @return the minimum size of the component
    316     */
    317    public Dimension minimumLayoutSize(final Container parent) {
    318
    319        Component c0, c1, c2, c3, c4, c5;
    320
    321        synchronized (parent.getTreeLock()) {
    322            final Insets insets = parent.getInsets();
    323            int componentIndex = 0;
    324            final int rowCount = this.rowHeights.length;
    325            for (int i = 0; i < this.columnWidths.length; i++) {
    326                this.columnWidths[i] = 0;
    327            }
    328            this.columns1and2Width = 0;
    329            this.columns4and5Width = 0;
    330            this.columns1to4Width = 0;
    331            this.columns1to5Width = 0;
    332            this.columns0to5Width = 0;
    333            final int totalHeight = 0;
    334            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    335
    336                final int format
    337                    = this.rowFormats[rowIndex % this.rowFormats.length];
    338
    339                switch (format) {
    340                    case FormatLayout.C:
    341                        c0 = parent.getComponent(componentIndex);
    342                        this.columns0to5Width = Math.max(
    343                            this.columns0to5Width, c0.getMinimumSize().width
    344                        );
    345                        componentIndex = componentIndex + 1;
    346                        break;
    347                    case FormatLayout.LC:
    348                        c0 = parent.getComponent(componentIndex);
    349                        c1 = parent.getComponent(componentIndex + 1);
    350                        updateLC(rowIndex,
    351                                 c0.getMinimumSize(),
    352                                 c1.getMinimumSize());
    353                        componentIndex = componentIndex + 2;
    354                        break;
    355                    case FormatLayout.LCB:
    356                        c0 = parent.getComponent(componentIndex);
    357                        c1 = parent.getComponent(componentIndex + 1);
    358                        c2 = parent.getComponent(componentIndex + 2);
    359                        updateLCB(rowIndex,
    360                                  c0.getMinimumSize(),
    361                                  c1.getMinimumSize(),
    362                                  c2.getMinimumSize());
    363                        componentIndex = componentIndex + 3;
    364                        break;
    365                    case FormatLayout.LCLC:
    366                        c0 = parent.getComponent(componentIndex);
    367                        c1 = parent.getComponent(componentIndex + 1);
    368                        c2 = parent.getComponent(componentIndex + 2);
    369                        c3 = parent.getComponent(componentIndex + 3);
    370                        updateLCLC(rowIndex,
    371                                   c0.getMinimumSize(),
    372                                   c1.getMinimumSize(),
    373                                   c2.getMinimumSize(),
    374                                   c3.getMinimumSize());
    375                        componentIndex = componentIndex + 3;
    376                        break;
    377                    case FormatLayout.LCBLC:
    378                        c0 = parent.getComponent(componentIndex);
    379                        c1 = parent.getComponent(componentIndex + 1);
    380                        c2 = parent.getComponent(componentIndex + 2);
    381                        c3 = parent.getComponent(componentIndex + 3);
    382                        c4 = parent.getComponent(componentIndex + 4);
    383                        updateLCBLC(rowIndex,
    384                                    c0.getMinimumSize(),
    385                                    c1.getMinimumSize(),
    386                                    c2.getMinimumSize(),
    387                                    c3.getMinimumSize(),
    388                                    c4.getMinimumSize());
    389                        componentIndex = componentIndex + 4;
    390                        break;
    391                    case FormatLayout.LCLCB:
    392                        c0 = parent.getComponent(componentIndex);
    393                        c1 = parent.getComponent(componentIndex + 1);
    394                        c2 = parent.getComponent(componentIndex + 2);
    395                        c3 = parent.getComponent(componentIndex + 3);
    396                        c4 = parent.getComponent(componentIndex + 4);
    397                        updateLCLCB(rowIndex,
    398                                    c0.getMinimumSize(),
    399                                    c1.getMinimumSize(),
    400                                    c2.getMinimumSize(),
    401                                    c3.getMinimumSize(),
    402                                    c4.getMinimumSize());
    403                        componentIndex = componentIndex + 4;
    404                        break;
    405                    case FormatLayout.LCBLCB:
    406                        c0 = parent.getComponent(componentIndex);
    407                        c1 = parent.getComponent(componentIndex + 1);
    408                        c2 = parent.getComponent(componentIndex + 2);
    409                        c3 = parent.getComponent(componentIndex + 3);
    410                        c4 = parent.getComponent(componentIndex + 4);
    411                        c5 = parent.getComponent(componentIndex + 5);
    412                        updateLCBLCB(rowIndex,
    413                                     c0.getMinimumSize(),
    414                                     c1.getMinimumSize(),
    415                                     c2.getMinimumSize(),
    416                                     c3.getMinimumSize(),
    417                                     c4.getMinimumSize(),
    418                                     c5.getMinimumSize());
    419                        componentIndex = componentIndex + 5;
    420                        break;
    421                }
    422            }
    423            complete();
    424            return new Dimension(this.totalWidth + insets.left + insets.right,
    425                                 totalHeight + (rowCount - 1) * this.rowGap
    426                                 + insets.top + insets.bottom);
    427        }
    428    }
    429
    430    /**
    431     * Performs the layout of the container.
    432     *
    433     * @param parent  the parent.
    434     */
    435    public void layoutContainer(final Container parent) {
    436        Component c0, c1, c2, c3, c4, c5;
    437
    438        synchronized (parent.getTreeLock()) {
    439            final Insets insets = parent.getInsets();
    440            int componentIndex = 0;
    441            final int rowCount = this.rowHeights.length;
    442            for (int i = 0; i < this.columnWidths.length; i++) {
    443                this.columnWidths[i] = 0;
    444            }
    445            this.columns1and2Width = 0;
    446            this.columns4and5Width = 0;
    447            this.columns1to4Width = 0;
    448            this.columns1to5Width = 0;
    449            this.columns0to5Width
    450                = parent.getBounds().width - insets.left - insets.right;
    451
    452            this.totalHeight = 0;
    453            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    454                final int format
    455                    = this.rowFormats[rowIndex % this.rowFormats.length];
    456                switch (format) {
    457                    case FormatLayout.C:
    458                        c0 = parent.getComponent(componentIndex);
    459                        updateC(rowIndex, c0.getPreferredSize());
    460                        componentIndex = componentIndex + 1;
    461                        break;
    462                    case FormatLayout.LC:
    463                        c0 = parent.getComponent(componentIndex);
    464                        c1 = parent.getComponent(componentIndex + 1);
    465                        updateLC(rowIndex, c0.getPreferredSize(),
    466                                c1.getPreferredSize());
    467                        componentIndex = componentIndex + 2;
    468                        break;
    469                    case FormatLayout.LCB:
    470                        c0 = parent.getComponent(componentIndex);
    471                        c1 = parent.getComponent(componentIndex + 1);
    472                        c2 = parent.getComponent(componentIndex + 2);
    473                        updateLCB(rowIndex,
    474                                  c0.getPreferredSize(),
    475                                  c1.getPreferredSize(),
    476                                  c2.getPreferredSize());
    477                        componentIndex = componentIndex + 3;
    478                        break;
    479                    case FormatLayout.LCLC:
    480                        c0 = parent.getComponent(componentIndex);
    481                        c1 = parent.getComponent(componentIndex + 1);
    482                        c2 = parent.getComponent(componentIndex + 2);
    483                        c3 = parent.getComponent(componentIndex + 3);
    484                        updateLCLC(rowIndex,
    485                                   c0.getPreferredSize(),
    486                                   c1.getPreferredSize(),
    487                                   c2.getPreferredSize(),
    488                                   c3.getPreferredSize());
    489                        componentIndex = componentIndex + 4;
    490                        break;
    491                    case FormatLayout.LCBLC:
    492                        c0 = parent.getComponent(componentIndex);
    493                        c1 = parent.getComponent(componentIndex + 1);
    494                        c2 = parent.getComponent(componentIndex + 2);
    495                        c3 = parent.getComponent(componentIndex + 3);
    496                        c4 = parent.getComponent(componentIndex + 4);
    497                        updateLCBLC(rowIndex,
    498                                    c0.getPreferredSize(),
    499                                    c1.getPreferredSize(),
    500                                    c2.getPreferredSize(),
    501                                    c3.getPreferredSize(),
    502                                    c4.getPreferredSize());
    503                        componentIndex = componentIndex + 5;
    504                        break;
    505                    case FormatLayout.LCLCB:
    506                        c0 = parent.getComponent(componentIndex);
    507                        c1 = parent.getComponent(componentIndex + 1);
    508                        c2 = parent.getComponent(componentIndex + 2);
    509                        c3 = parent.getComponent(componentIndex + 3);
    510                        c4 = parent.getComponent(componentIndex + 4);
    511                        updateLCLCB(rowIndex,
    512                                    c0.getPreferredSize(),
    513                                    c1.getPreferredSize(),
    514                                    c2.getPreferredSize(),
    515                                    c3.getPreferredSize(),
    516                                    c4.getPreferredSize());
    517                        componentIndex = componentIndex + 5;
    518                        break;
    519                    case FormatLayout.LCBLCB:
    520                        c0 = parent.getComponent(componentIndex);
    521                        c1 = parent.getComponent(componentIndex + 1);
    522                        c2 = parent.getComponent(componentIndex + 2);
    523                        c3 = parent.getComponent(componentIndex + 3);
    524                        c4 = parent.getComponent(componentIndex + 4);
    525                        c5 = parent.getComponent(componentIndex + 5);
    526                        updateLCBLCB(rowIndex,
    527                                     c0.getPreferredSize(),
    528                                     c1.getPreferredSize(),
    529                                     c2.getPreferredSize(),
    530                                     c3.getPreferredSize(),
    531                                     c4.getPreferredSize(),
    532                                     c5.getPreferredSize());
    533                        componentIndex = componentIndex + 6;
    534                        break;
    535                }
    536            }
    537            complete();
    538
    539            componentIndex = 0;
    540            int rowY = insets.top;
    541            final int[] rowX = new int[6];
    542            rowX[0] = insets.left;
    543            rowX[1] = rowX[0] + this.columnWidths[0] + this.columnGaps[0];
    544            rowX[2] = rowX[1] + this.columnWidths[1] + this.columnGaps[1];
    545            rowX[3] = rowX[2] + this.columnWidths[2] + this.columnGaps[2];
    546            rowX[4] = rowX[3] + this.columnWidths[3] + this.columnGaps[3];
    547            rowX[5] = rowX[4] + this.columnWidths[4] + this.columnGaps[4];
    548            final int w1to2 = this.columnWidths[1] + this.columnGaps[1]
    549                              + this.columnWidths[2];
    550            final int w4to5 = this.columnWidths[4] + this.columnGaps[4]
    551                              + this.columnWidths[5];
    552            final int w1to4 = w1to2 + this.columnGaps[2] + this.columnWidths[3]
    553                        + this.columnGaps[3] + this.columnWidths[4];
    554            final int w1to5 = w1to4 + this.columnGaps[4] + this.columnWidths[5];
    555            final int w0to5 = w1to5 + this.columnWidths[0] + this.columnGaps[0];
    556            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
    557                final int format
    558                    = this.rowFormats[rowIndex % this.rowFormats.length];
    559
    560                switch (format) {
    561                case FormatLayout.C:
    562                    c0 = parent.getComponent(componentIndex);
    563                    c0.setBounds(rowX[0], rowY, w0to5,
    564                            c0.getPreferredSize().height);
    565                    componentIndex = componentIndex + 1;
    566                    break;
    567                case FormatLayout.LC:
    568                    c0 = parent.getComponent(componentIndex);
    569                    c0.setBounds(
    570                        rowX[0],
    571                        rowY + (this.rowHeights[rowIndex]
    572                                     - c0.getPreferredSize().height) / 2,
    573                        this.columnWidths[0], c0.getPreferredSize().height
    574                    );
    575                    c1 = parent.getComponent(componentIndex + 1);
    576                    c1.setBounds(
    577                        rowX[1],
    578                        rowY + (this.rowHeights[rowIndex]
    579                                     - c1.getPreferredSize().height) / 2,
    580                        w1to5, c1.getPreferredSize().height
    581                    );
    582                    componentIndex = componentIndex + 2;
    583                    break;
    584                case FormatLayout.LCB:
    585                    c0 = parent.getComponent(componentIndex);
    586                    c0.setBounds(
    587                        rowX[0],
    588                        rowY + (this.rowHeights[rowIndex]
    589                                     - c0.getPreferredSize().height) / 2,
    590                        this.columnWidths[0], c0.getPreferredSize().height
    591                    );
    592                    c1 = parent.getComponent(componentIndex + 1);
    593                    c1.setBounds(
    594                        rowX[1],
    595                        rowY + (this.rowHeights[rowIndex]
    596                                    - c1.getPreferredSize().height) / 2,
    597                        w1to4, c1.getPreferredSize().height
    598                    );
    599                    c2 = parent.getComponent(componentIndex + 2);
    600                    c2.setBounds(
    601                        rowX[5],
    602                        rowY + (this.rowHeights[rowIndex]
    603                                    - c2.getPreferredSize().height) / 2,
    604                        this.columnWidths[5], c2.getPreferredSize().height
    605                    );
    606                    componentIndex = componentIndex + 3;
    607                    break;
    608                case FormatLayout.LCLC:
    609                    c0 = parent.getComponent(componentIndex);
    610                    c0.setBounds(
    611                        rowX[0],
    612                        rowY + (this.rowHeights[rowIndex]
    613                                    - c0.getPreferredSize().height) / 2,
    614                        this.columnWidths[0], c0.getPreferredSize().height
    615                    );
    616                    c1 = parent.getComponent(componentIndex + 1);
    617                    c1.setBounds(
    618                        rowX[1],
    619                        rowY + (this.rowHeights[rowIndex]
    620                                    - c1.getPreferredSize().height) / 2,
    621                        w1to2, c1.getPreferredSize().height
    622                    );
    623                    c2 = parent.getComponent(componentIndex + 2);
    624                    c2.setBounds(
    625                        rowX[3],
    626                        rowY + (this.rowHeights[rowIndex]
    627                                    - c2.getPreferredSize().height) / 2,
    628                        this.columnWidths[3], c2.getPreferredSize().height
    629                    );
    630                    c3 = parent.getComponent(componentIndex + 3);
    631                    c3.setBounds(
    632                        rowX[4],
    633                        rowY + (this.rowHeights[rowIndex]
    634                                    - c3.getPreferredSize().height) / 2,
    635                        w4to5, c3.getPreferredSize().height
    636                    );
    637                    componentIndex = componentIndex + 4;
    638                    break;
    639                case FormatLayout.LCBLC:
    640                    c0 = parent.getComponent(componentIndex);
    641                    c0.setBounds(
    642                        rowX[0],
    643                        rowY + (this.rowHeights[rowIndex]
    644                                    - c0.getPreferredSize().height) / 2,
    645                        this.columnWidths[0], c0.getPreferredSize().height
    646                    );
    647                    c1 = parent.getComponent(componentIndex + 1);
    648                    c1.setBounds(
    649                        rowX[1],
    650                        rowY + (this.rowHeights[rowIndex]
    651                                    - c1.getPreferredSize().height) / 2,
    652                        this.columnWidths[1], c1.getPreferredSize().height
    653                    );
    654                    c2 = parent.getComponent(componentIndex + 2);
    655                    c2.setBounds(
    656                        rowX[2],
    657                        rowY + (this.rowHeights[rowIndex]
    658                                    - c2.getPreferredSize().height) / 2,
    659                        this.columnWidths[2], c2.getPreferredSize().height
    660                    );
    661                    c3 = parent.getComponent(componentIndex + 3);
    662                    c3.setBounds(
    663                        rowX[3],
    664                        rowY + (this.rowHeights[rowIndex]
    665                                    - c3.getPreferredSize().height) / 2,
    666                        this.columnWidths[3], c3.getPreferredSize().height
    667                    );
    668                    c4 = parent.getComponent(componentIndex + 4);
    669                    c4.setBounds(
    670                        rowX[4],
    671                        rowY + (this.rowHeights[rowIndex]
    672                                    - c4.getPreferredSize().height) / 2,
    673                        w4to5, c4.getPreferredSize().height
    674                    );
    675                    componentIndex = componentIndex + 5;
    676                    break;
    677                case FormatLayout.LCLCB:
    678                    c0 = parent.getComponent(componentIndex);
    679                    c0.setBounds(
    680                        rowX[0],
    681                        rowY + (this.rowHeights[rowIndex]
    682                                    - c0.getPreferredSize().height) / 2,
    683                        this.columnWidths[0], c0.getPreferredSize().height
    684                    );
    685                    c1 = parent.getComponent(componentIndex + 1);
    686                    c1.setBounds(
    687                        rowX[1],
    688                        rowY + (this.rowHeights[rowIndex]
    689                                    - c1.getPreferredSize().height) / 2,
    690                        w1to2, c1.getPreferredSize().height
    691                    );
    692                    c2 = parent.getComponent(componentIndex + 2);
    693                    c2.setBounds(
    694                        rowX[3],
    695                        rowY + (this.rowHeights[rowIndex]
    696                                    - c2.getPreferredSize().height) / 2,
    697                        this.columnWidths[3], c2.getPreferredSize().height
    698                    );
    699                    c3 = parent.getComponent(componentIndex + 3);
    700                    c3.setBounds(
    701                        rowX[4],
    702                        rowY + (this.rowHeights[rowIndex]
    703                                    - c3.getPreferredSize().height) / 2,
    704                        this.columnWidths[4], c3.getPreferredSize().height
    705                    );
    706                    c4 = parent.getComponent(componentIndex + 4);
    707                    c4.setBounds(
    708                        rowX[5],
    709                        rowY + (this.rowHeights[rowIndex]
    710                                    - c4.getPreferredSize().height) / 2,
    711                        this.columnWidths[5], c4.getPreferredSize().height
    712                    );
    713                    componentIndex = componentIndex + 5;
    714                    break;
    715                case FormatLayout.LCBLCB:
    716                    c0 = parent.getComponent(componentIndex);
    717                    c0.setBounds(
    718                        rowX[0],
    719                        rowY + (this.rowHeights[rowIndex]
    720                                     - c0.getPreferredSize().height) / 2,
    721                        this.columnWidths[0], c0.getPreferredSize().height
    722                    );
    723                    c1 = parent.getComponent(componentIndex + 1);
    724                    c1.setBounds(
    725                        rowX[1],
    726                        rowY + (this.rowHeights[rowIndex]
    727                                     - c1.getPreferredSize().height) / 2,
    728                        this.columnWidths[1], c1.getPreferredSize().height
    729                    );
    730                    c2 = parent.getComponent(componentIndex + 2);
    731                    c2.setBounds(
    732                        rowX[2],
    733                        rowY + (this.rowHeights[rowIndex]
    734                                     - c2.getPreferredSize().height) / 2,
    735                        this.columnWidths[2], c2.getPreferredSize().height
    736                    );
    737                    c3 = parent.getComponent(componentIndex + 3);
    738                    c3.setBounds(
    739                        rowX[3],
    740                        rowY + (this.rowHeights[rowIndex]
    741                                     - c3.getPreferredSize().height) / 2,
    742                        this.columnWidths[3], c3.getPreferredSize().height
    743                    );
    744                    c4 = parent.getComponent(componentIndex + 4);
    745                    c4.setBounds(
    746                        rowX[4],
    747                        rowY + (this.rowHeights[rowIndex]
    748                                     - c4.getPreferredSize().height) / 2,
    749                        this.columnWidths[4], c4.getPreferredSize().height
    750                    );
    751                    c5 = parent.getComponent(componentIndex + 5);
    752                    c5.setBounds(
    753                        rowX[5],
    754                        rowY + (this.rowHeights[rowIndex]
    755                                     - c5.getPreferredSize().height) / 2,
    756                        this.columnWidths[5], c5.getPreferredSize().height
    757                    );
    758                    componentIndex = componentIndex + 6;
    759                    break;
    760                    }
    761                rowY = rowY + this.rowHeights[rowIndex] + this.rowGap;
    762            }
    763        }
    764    }
    765
    766    /**
    767     * Processes a row in 'C' format.
    768     *
    769     * @param rowIndex  the row index.
    770     * @param d0  dimension 0.
    771     */
    772    protected void updateC(final int rowIndex, final Dimension d0) {
    773        this.rowHeights[rowIndex] = d0.height;
    774        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    775        this.columns0to5Width = Math.max(this.columns0to5Width, d0.width);
    776    }
    777
    778    /**
    779     * Processes a row in 'LC' format.
    780     *
    781     * @param rowIndex  the row index.
    782     * @param d0  dimension 0.
    783     * @param d1  dimension 1.
    784     */
    785    protected void updateLC(final int rowIndex, final Dimension d0,
    786                            final Dimension d1) {
    787
    788        this.rowHeights[rowIndex] = Math.max(d0.height, d1.height);
    789        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    790        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    791        this.columns1to5Width = Math.max(this.columns1to5Width, d1.width);
    792
    793    }
    794
    795    /**
    796     * Processes a row in 'LCB' format.
    797     *
    798     * @param rowIndex  the row index.
    799     * @param d0  dimension 0.
    800     * @param d1  dimension 1.
    801     * @param d2  dimension 2.
    802     */
    803    protected void updateLCB(final int rowIndex,
    804                             final Dimension d0, final Dimension d1,
    805                             final Dimension d2) {
    806
    807        this.rowHeights[rowIndex]
    808               = Math.max(d0.height, Math.max(d1.height, d2.height));
    809        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    810        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    811        this.columns1to4Width = Math.max(this.columns1to4Width, d1.width);
    812        this.columnWidths[5] = Math.max(this.columnWidths[5], d2.width);
    813
    814    }
    815
    816    /**
    817     * Processes a row in 'LCLC' format.
    818     *
    819     * @param rowIndex  the row index.
    820     * @param d0  dimension 0.
    821     * @param d1  dimension 1.
    822     * @param d2  dimension 2.
    823     * @param d3  dimension 3.
    824     */
    825    protected void updateLCLC(final int rowIndex, final Dimension d0,
    826                              final Dimension d1, final Dimension d2,
    827                              final Dimension d3) {
    828
    829        this.rowHeights[rowIndex] = Math.max(Math.max(d0.height, d1.height),
    830                                        Math.max(d2.height, d3.height));
    831        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    832        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    833        this.columns1and2Width = Math.max(this.columns1and2Width, d1.width);
    834        this.columnWidths[3] = Math.max(this.columnWidths[3], d2.width);
    835        this.columns4and5Width = Math.max(this.columns4and5Width, d3.width);
    836    }
    837
    838    /**
    839     * Processes a row in 'LCBLC' format.
    840     *
    841     * @param rowIndex  the row index.
    842     * @param d0  dimension 0.
    843     * @param d1  dimension 1.
    844     * @param d2  dimension 2.
    845     * @param d3  dimension 3.
    846     * @param d4  dimension 4.
    847     */
    848    protected void updateLCBLC(final int rowIndex, final Dimension d0,
    849                               final Dimension d1, final Dimension d2,
    850                               final Dimension d3, final Dimension d4) {
    851
    852        this.rowHeights[rowIndex] = (Math.max(
    853            d0.height,
    854            Math.max(Math.max(d1.height, d2.height),
    855            Math.max(d3.height, d4.height)))
    856        );
    857        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    858        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    859        this.columnWidths[1] = Math.max(this.columnWidths[1], d1.width);
    860        this.columnWidths[2] = Math.max(this.columnWidths[2], d2.width);
    861        this.columnWidths[3] = Math.max(this.columnWidths[3], d3.width);
    862        this.columns4and5Width = Math.max(this.columns4and5Width, d4.width);
    863
    864    }
    865
    866    /**
    867     * Processes a row in 'LCLCB' format.
    868     *
    869     * @param rowIndex  the row index.
    870     * @param d0  dimension 0.
    871     * @param d1  dimension 1.
    872     * @param d2  dimension 2.
    873     * @param d3  dimension 3.
    874     * @param d4  dimension 4.
    875     */
    876    protected void updateLCLCB(final int rowIndex, final Dimension d0,
    877                               final Dimension d1, final Dimension d2,
    878                               final Dimension d3, final Dimension d4) {
    879
    880        this.rowHeights[rowIndex] = (Math.max(d0.height,
    881                                     Math.max(Math.max(d1.height, d2.height),
    882                                              Math.max(d3.height, d4.height))));
    883        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    884        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    885        this.columns1and2Width = Math.max(this.columns1and2Width, d1.width);
    886        this.columnWidths[3] = Math.max(this.columnWidths[3], d2.width);
    887        this.columnWidths[4] = Math.max(this.columnWidths[4], d3.width);
    888        this.columnWidths[5] = Math.max(this.columnWidths[5], d4.width);
    889
    890    }
    891
    892    /**
    893     * Processes a row in 'LCBLCB' format.
    894     *
    895     * @param rowIndex  the row index.
    896     * @param d0  dimension 0.
    897     * @param d1  dimension 1.
    898     * @param d2  dimension 2.
    899     * @param d3  dimension 3.
    900     * @param d4  dimension 4.
    901     * @param d5  dimension 5.
    902     */
    903    protected void updateLCBLCB(final int rowIndex,
    904                                final Dimension d0, final Dimension d1,
    905                                final Dimension d2,
    906                                final Dimension d3, final Dimension d4,
    907                                final Dimension d5) {
    908
    909        this.rowHeights[rowIndex] = Math.max(
    910            Math.max(d0.height, d1.height),
    911            Math.max(Math.max(d2.height, d3.height),
    912                     Math.max(d4.height, d5.height))
    913        );
    914        this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
    915        this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
    916        this.columnWidths[1] = Math.max(this.columnWidths[1], d1.width);
    917        this.columnWidths[2] = Math.max(this.columnWidths[2], d2.width);
    918        this.columnWidths[3] = Math.max(this.columnWidths[3], d3.width);
    919        this.columnWidths[4] = Math.max(this.columnWidths[4], d4.width);
    920        this.columnWidths[5] = Math.max(this.columnWidths[5], d5.width);
    921
    922    }
    923
    924    /**
    925     * Finishes of the processing.
    926     */
    927    public void complete() {
    928
    929        this.columnWidths[1] = Math.max(
    930             this.columnWidths[1],
    931             this.columns1and2Width - this.columnGaps[1] - this.columnWidths[2]
    932        );
    933
    934        this.columnWidths[4] = Math.max(
    935            this.columnWidths[4],
    936            Math.max(
    937                this.columns4and5Width - this.columnGaps[4]
    938                - this.columnWidths[5],
    939                Math.max(
    940                    this.columns1to4Width - this.columnGaps[1]
    941                        - this.columnGaps[2] - this.columnGaps[3]
    942                        - this.columnWidths[1] - this.columnWidths[2]
    943                        - this.columnWidths[3],
    944                    this.columns1to5Width - this.columnGaps[1]
    945                        - this.columnGaps[2] - this.columnGaps[3]
    946                        - this.columnWidths[1] - this.columnWidths[2]
    947                        - this.columnWidths[3] - this.columnGaps[4]
    948                )
    949            )
    950        );
    951
    952        int leftWidth = this.columnWidths[0] + this.columnGaps[0]
    953                      + this.columnWidths[1] + this.columnGaps[1]
    954                      + this.columnWidths[2];
    955
    956        int rightWidth = this.columnWidths[3] + this.columnGaps[3]
    957                       + this.columnWidths[4] + this.columnGaps[4]
    958                       + this.columnWidths[5];
    959
    960        if (splitLayout()) {
    961            if (leftWidth > rightWidth) {
    962                final int mismatch = leftWidth - rightWidth;
    963                this.columnWidths[4] = this.columnWidths[4] + mismatch;
    964                rightWidth = rightWidth + mismatch;
    965            }
    966            else {
    967                final int mismatch = rightWidth - leftWidth;
    968                this.columnWidths[1] = this.columnWidths[1] + mismatch;
    969                leftWidth = leftWidth + mismatch;
    970            }
    971        }
    972
    973        this.totalWidth = leftWidth + this.columnGaps[2] + rightWidth;
    974
    975        if (this.columns0to5Width > this.totalWidth) {
    976            final int spaceToAdd = (this.columns0to5Width - this.totalWidth);
    977            if (splitLayout()) {
    978                final int halfSpaceToAdd = spaceToAdd / 2;
    979                this.columnWidths[1] = this.columnWidths[1] + halfSpaceToAdd;
    980                this.columnWidths[4] = this.columnWidths[4] + spaceToAdd
    981                    - halfSpaceToAdd;
    982                this.totalWidth = this.totalWidth + spaceToAdd;
    983            }
    984            else {
    985                this.columnWidths[1] = this.columnWidths[1] + spaceToAdd;
    986                this.totalWidth = this.totalWidth + spaceToAdd;
    987            }
    988        }
    989
    990    }
    991
    992    /**
    993     * Returns true if this layout involves a split into two sections.
    994     *
    995     * @return <code>true</code> if this layout involves a split into two
    996     *         sections.
    997     */
    998    private boolean splitLayout() {
    999        for (int i = 0; i < this.rowFormats.length; i++) {
    1000            if (this.rowFormats[i] > FormatLayout.LCB) {
    1001                return true;
    1002            }
    1003        }
    1004        return false;
    1005    }
    1006
    1007    /**
    1008     * Not used.
    1009     *
    1010     * @param comp  the component.
    1011     */
    1012    public void addLayoutComponent(final Component comp) {
    1013        // not used
    1014    }
    1015
    1016    /**
    1017     * Not used.
    1018     *
    1019     * @param comp  the component.
    1020     */
    1021    public void removeLayoutComponent(final Component comp) {
    1022        // not used
    1023    }
    1024
    1025    /**
    1026     * Not used.
    1027     *
    1028     * @param name  the component name.
    1029     * @param comp  the component.
    1030     */
    1031    public void addLayoutComponent(final String name, final Component comp) {
    1032        // not used
    1033    }
    1034
    1035    /**
    1036     * Not used.
    1037     *
    1038     * @param name  the component name.
    1039     * @param comp  the component.
    1040     */
    1041    public void removeLayoutComponent(final String name, final Component comp) {
    1042        // not used
    1043    }
    1044
    1045}