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}