Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/gui4j/core/swing/TableLayout.java


1   /*
2    * June 2006: This is the original file except of this paragraph and 
3    * for consistency, the original package name info.clearthought
4    * was renamed.  
5    */
6   /*
7    * ====================================================================
8    *
9    * The Clearthought Software License, Version 1.0
10   *
11   * Copyright (c) 2001 Daniel Barbalace.  All rights reserved.
12   *
13   * Redistribution and use in source and binary forms, with or without
14   * modification, are permitted provided that the following conditions
15   * are met:
16   *
17   * 1. Redistributions of source code must retain the above copyright
18   *    notice, this list of conditions and the following disclaimer.
19   *
20   * 2. The original software may not be altered.  However, the classes
21   *    provided may be subclasses as long as the subclasses are not
22   *    packaged in the info.clearthought package or any subpackage of
23   *    info.clearthought.
24   *
25   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
26   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28   * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR, AFFILATED BUSINESSES,
29   * OR ANYONE ELSE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
32   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
35   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36   * SUCH DAMAGE.
37   * ====================================================================
38   */
39  
40  package org.gui4j.core.swing;
41  
42  import java.awt.Component;
43  import java.awt.Container;
44  import java.awt.Dimension;
45  import java.awt.Insets;
46  import java.util.LinkedList;
47  import java.util.ListIterator;
48  
49  /**
50   * TableLayout is a layout manager that arranges components in rows and columns
51   * like a spreadsheet.  TableLayout allows each row or column to be a different
52   * size.  A row or column can be given an absolute size in pixels, a percentage
53   * of the available space, or it can grow and shrink to fill the remaining space
54   * after other rows and columns have been resized.
55   *
56   * <p>Using spreadsheet terminology, a cell is the intersection of a row and
57   * column.  Cells have finite, non-negative sizes measured in pixels.  The
58   * dimensions of a cell depend solely upon the dimensions of its row and column.
59   * </p>
60   *
61   * <p>A component occupies a rectangular group of one or more cells.  The
62   * component can be aligned in four ways within that cell.</p>
63   *
64   * <p>A component can be stretched horizontally to fit the cell set (full
65   * justification), or it can be placed in the center of the cell.  The
66   * component could also be left justified or right justified.  Similarly, the
67   * component can be full, center, top, or bottom justified along the
68   *
69   * <pre>
70   * public static void main (String args[])
71   * {
72   *     // Create a frame
73   *     Frame frame = new Frame("Example of TableLayout");
74   *     frame.setBounds (100, 100, 300, 300);
75   * <spc>
76   *     // Create a TableLayout for the frame
77   *     double border = 10;
78   *     double size[][] =
79   *         {{border, 0.10, 20, TableLayout.FILL, 20, 0.20, border},  // Columns
80   *          {border, 0.20, 20, TableLayout.FILL, 20, 0.20, border}}; // Rows
81   * <spc>
82   *     frame.setLayout (new TableLayout(size));
83   * <spc>
84   *     // Create some buttons
85   *     String label[] = {"Top", "Bottom", "Left", "Right", "Center", "Overlap"};
86   *     Button button[] = new Button[label.length];
87   * <spc>
88   *     for (int i = 0; i < label.length; i++)
89   *         button[i] = new Button(label[i]);
90   * <spc>
91   *     // Add buttons
92   *     frame.add (button[0], "1, 1, 5, 1"); // Top
93   *     frame.add (button[1], "1, 5, 5, 5"); // Bottom
94   *     frame.add (button[2], "1, 3      "); // Left
95   *     frame.add (button[3], "5, 3      "); // Right
96   *     frame.add (button[4], "3, 3, c, c"); // Center
97   *     frame.add (button[5], "3, 3, 3, 5"); // Overlap
98   * <spc>
99   *     // Allow user to close the window to terminate the program
100  *     frame.addWindowListener
101  *         (new WindowListener()
102  *             {
103  *                 public void windowClosing (WindowEvent e)
104  *                 {
105  *                     System.exit (0);
106  *                 }
107  * <spc>
108  *                 public void windowOpened (WindowEvent e) {}
109  *                 public void windowClosed (WindowEvent e) {}
110  *                 public void windowIconified (WindowEvent e) {}
111  *                 public void windowDeiconified (WindowEvent e) {}
112  *                 public void windowActivated (WindowEvent e) {}
113  *                 public void windowDeactivated (WindowEvent e) {}
114  *             }
115  *         );
116  * <spc>
117  *     // Show frame
118  *     frame.show();
119  * }
120  * </pre>
121  *
122  * @version 2.1 4/26/02
123  * @author  Daniel E. Barbalace
124  */
125 
126 public class TableLayout implements java.awt.LayoutManager2, java.io.Serializable, TableLayoutConstants
127 {
128 
129     /*
130         Note: In this file, a cr refers to either a column or a row.  cr[C] always
131         means column and cr[R] always means row.  A cr size is either a column
132         width or a row Height.  TableLayout views columns and rows as being
133         conceptually symmetric.  Therefore, much of the code applies to both
134         columns and rows, and the use of the cr terminology eliminates redundancy.
135         Also, for ease of reading, z always indicates a parameter whose value is
136         either C or R.
137     */
138 
139     /** Default row/column size */
140     protected static final double defaultSize[][] = { {
141         }, {
142         }
143     };
144 
145     /** Indicates a column */
146     protected static final int C = 0;
147 
148     /** Indicates a row */
149     protected static final int R = 1;
150 
151     /** Sizes of crs expressed in absolute and relative terms */
152     protected double crSpec[][] = { null, null };
153 
154     /** Sizes of crs in pixels */
155     protected int crSize[][] = { null, null };
156 
157     /** Offsets of crs in pixels.  The left boarder of column n is at
158      crOffset[C][n] and the right boarder is at cr[C][n + 1] for all
159      columns including the last one.  crOffset[C].length = crSize[C].length + 1 */
160     protected int crOffset[][] = { null, null };
161 
162     /** List of components and their sizes */
163     protected LinkedList list;
164 
165     /** Indicates whether or not the size of the cells are known for the last known
166      size of the container.  If dirty is true or the container has been resized,
167      the cell sizes must be recalculated using calculateSize. */
168     protected boolean dirty;
169 
170     /** Previous known width of the container */
171     protected int oldWidth;
172 
173     /** Previous known height of the container */
174     protected int oldHeight;
175 
176     /** Horizontal gap between columns */
177     protected int hGap;
178 
179     /** Vertical gap between rows */
180     protected int vGap;
181 
182     //******************************************************************************
183     //** Constructors                                                            ***
184     //******************************************************************************
185 
186     /**
187      * Constructs an instance of TableLayout.  This TableLayout will have one row
188      * and one column.
189      */
190 
191     public TableLayout()
192     {
193         this(defaultSize);
194     }
195 
196     /**
197      * Constructs an instance of TableLayout.
198      *
199      * @param size    widths of columns and heights of rows in the format,
200      *                {{col0, col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}}
201      *                If this parameter is invalid, the TableLayout will have
202      *                exactly one row and one column.
203      */
204 
205     public TableLayout(double size[][])
206     {
207         // Make sure rows and columns and nothing else is specified
208         if ((size != null) && (size.length == 2))
209         {
210             // Get the rows and columns
211             double tempCol[] = size[0];
212             double tempRow[] = size[1];
213 
214             // Create new rows and columns
215             crSpec[C] = new double[tempCol.length];
216             crSpec[R] = new double[tempRow.length];
217 
218             // Copy rows and columns
219             System.arraycopy(tempCol, 0, crSpec[C], 0, crSpec[C].length);
220             System.arraycopy(tempRow, 0, crSpec[R], 0, crSpec[R].length);
221 
222             // Make sure rows and columns are valid
223             for (int counter = 0; counter < crSpec[C].length; counter++)
224                 if ((crSpec[C][counter] < 0.0)
225                     && (crSpec[C][counter] != FILL)
226                     && (crSpec[C][counter] != PREFERRED)
227                     && (crSpec[C][counter] != MINIMUM))
228                 {
229                     crSpec[C][counter] = 0.0;
230                 }
231 
232             for (int counter = 0; counter < crSpec[R].length; counter++)
233                 if ((crSpec[R][counter] < 0.0)
234                     && (crSpec[R][counter] != FILL)
235                     && (crSpec[R][counter] != PREFERRED)
236                     && (crSpec[R][counter] != MINIMUM))
237                 {
238                     crSpec[R][counter] = 0.0;
239                 }
240         }
241         else
242         {
243             throw new IllegalArgumentException(
244                 "Parameter size should be an array, a[2], where a[0] is the "
245                     + "is an array of column widths and a[1] is an array or row "
246                     + "heights.");
247         }
248 
249         // Create an empty list of components
250         list = new LinkedList();
251 
252         // Indicate that the cell sizes are not known
253         dirty = true;
254     }
255 
256     //******************************************************************************
257     //** Get/Set methods                                                         ***
258     //******************************************************************************
259 
260     /**
261      * Gets the constraints of a given component.
262      *
263      * @param component    desired component
264      *
265      * @return If the given component is found, the constraints associated with
266      *         that component.  If the given component is null or is not found,
267      *         null is returned.
268      */
269 
270     public TableLayoutConstraints getConstraints(Component component)
271     {
272         ListIterator iterator = list.listIterator(0);
273 
274         while (iterator.hasNext())
275         {
276             Entry entry = (Entry) iterator.next();
277 
278             if (entry.component == component)
279                 return new TableLayoutConstraints(
280                     entry.cr1[C],
281                     entry.cr1[R],
282                     entry.cr2[C],
283                     entry.cr2[R],
284                     entry.alignment[C],
285                     entry.alignment[R]);
286         }
287 
288         return null;
289     }
290 
291     /**
292      * Sets the constraints of a given component.
293      *
294      * @param component     desired component.  This parameter cannot be null.
295      * @param constraint    new set of constraints.  This parameter cannot be null.
296      */
297 
298     public void setConstraints(Component component, TableLayoutConstraints constraint)
299     {
300         // Check parameters
301         if (component == null)
302             throw new IllegalArgumentException("Parameter component cannot be null.");
303         else if (constraint == null)
304             throw new IllegalArgumentException("Parameter constraint cannot be null.");
305 
306         // Find and update constraints for the given component
307         ListIterator iterator = list.listIterator(0);
308 
309         while (iterator.hasNext())
310         {
311             Entry entry = (Entry) iterator.next();
312 
313             if (entry.component == component)
314                 iterator.set(new Entry(component, constraint));
315         }
316     }
317 
318     /**
319      * Adjusts the number and sizes of rows in this layout.  After calling this
320      * method, the caller should request this layout manager to perform the
321      * layout.  This can be done with the following code:
322      *
323      * <pre>
324      *     layout.layoutContainer(container);
325      *     container.repaint();
326      * </pre>
327      *
328      * or
329      *
330      * <pre>
331      *     window.pack()
332      * </pre>
333      *
334      * If this is not done, the changes in the layout will not be seen until the
335      * container is resized.
336      *
337      * @param column    heights of each of the columns
338      */
339 
340     public void setColumn(double column[])
341     {
342         setCr(C, column);
343     }
344 
345     /**
346      * Adjusts the number and sizes of rows in this layout.  After calling this
347      * method, the caller should request this layout manager to perform the
348      * layout.  This can be done with the following code:
349      *
350      * <code>
351      *     layout.layoutContainer(container);
352      *     container.repaint();
353      * </code>
354      *
355      * or
356      *
357      * <pre>
358      *     window.pack()
359      * </pre>
360      *
361      * If this is not done, the changes in the layout will not be seen until the
362      * container is resized.
363      *
364      * @param row    widths of each of the rows.  This parameter cannot be null.
365      */
366 
367     public void setRow(double row[])
368     {
369         setCr(R, row);
370     }
371 
372     /**
373      * Sets the sizes of rows or columns for the methods setRow or setColumn.
374      * 
375      * @param z       indicates row or column
376      * @param size    new cr size
377      */
378 
379     protected void setCr(int z, double size[])
380     {
381         // Copy crs
382         crSpec[z] = new double[size.length];
383         System.arraycopy(size, 0, crSpec[z], 0, crSpec[z].length);
384 
385         // Make sure rows are valid
386         for (int counter = 0; counter < crSpec[z].length; counter++)
387             if ((crSpec[z][counter] < 0.0)
388                 && (crSpec[z][counter] != FILL)
389                 && (crSpec[z][counter] != PREFERRED)
390                 && (crSpec[z][counter] != MINIMUM))
391             {
392                 crSpec[z][counter] = 0.0;
393             }
394 
395         // Indicate that the cell sizes are not known
396         dirty = true;
397     }
398 
399     /**
400      * Adjusts the width of a single column in this layout.  After calling this
401      * method, the caller should request this layout manager to perform the
402      * layout.  This can be done with the following code:
403      *
404      * <code>
405      *     layout.layoutContainer(container);
406      *     container.repaint();
407      * </code>
408      *
409      * or
410      *
411      * <pre>
412      *     window.pack()
413      * </pre>
414      *
415      * If this is not done, the changes in the layout will not be seen until the
416      * container is resized.
417      *
418      * @param i       zero-based index of column to set.  If this parameter is not
419      *                valid, an ArrayOutOfBoundsException will be thrown.
420      * @param size    width of the column.  This parameter cannot be null.
421      */
422 
423     public void setColumn(int i, double size)
424     {
425         setCr(C, i, size);
426     }
427 
428     /**
429      * Adjusts the height of a single row in this layout.  After calling this
430      * method, the caller should request this layout manager to perform the
431      * layout.  This can be done with the following code:
432      *
433      * <code>
434      *     layout.layoutContainer(container);
435      *     container.repaint();
436      * </code>
437      *
438      * or
439      *
440      * <pre>
441      *     window.pack()
442      * </pre>
443      *
444      * If this is not done, the changes in the layout will not be seen until the
445      * container is resized.
446      *
447      * @param i       zero-based index of row to set.  If this parameter is not
448      *                valid, an ArrayOutOfBoundsException will be thrown.
449      * @param size    height of the row.  This parameter cannot be null.
450      */
451 
452     public void setRow(int i, double size)
453     {
454         setCr(R, i, size);
455     }
456 
457     /**
458      * Sets the sizes of rows or columns for the methods setRow or setColumn.
459      * 
460      * @param z       indicates row or column
461      * @param i       indicates which cr to resize
462      * @param size    new cr size
463      */
464 
465     protected void setCr(int z, int i, double size)
466     {
467         // Make sure size is valid
468         if ((size < 0.0) && (size != FILL) && (size != PREFERRED) && (size != MINIMUM))
469         {
470             size = 0.0;
471         }
472 
473         // Copy new size
474         crSpec[z][i] = size;
475 
476         // Indicate that the cell sizes are not known
477         dirty = true;
478     }
479 
480     /**
481      * Gets the sizes of columns in this layout.
482      *
483      * @return widths of each of the columns
484      */
485 
486     public double[] getColumn()
487     {
488         // Copy columns
489         double column[] = new double[crSpec[C].length];
490         System.arraycopy(crSpec[C], 0, column, 0, column.length);
491 
492         return column;
493     }
494 
495     /**
496      * Gets the height of a single row in this layout.
497      *
498      * @return height of the requested row
499      */
500 
501     public double[] getRow()
502     {
503         // Copy rows
504         double row[] = new double[crSpec[R].length];
505         System.arraycopy(crSpec[R], 0, row, 0, row.length);
506 
507         return row;
508     }
509 
510     /**
511      * Gets the width of a single column in this layout.
512      *
513      * @param i    zero-based index of row to get.  If this parameter is not valid,
514      *             an ArrayOutOfBoundsException will be thrown.
515      *
516      * @return width of the requested column
517      */
518 
519     public double getColumn(int i)
520     {
521         return crSpec[C][i];
522     }
523 
524     /**
525      * Gets the sizes of a row in this layout.
526      *
527      * @param i    zero-based index of row to get.  If this parameter is not valid,
528      *             an ArrayOutOfBoundsException will be thrown.
529      *
530      * @return height of each of the requested row
531      */
532 
533     public double getRow(int i)
534     {
535         return crSpec[R][i];
536     }
537 
538     /**
539      * Gets the number of columns in this layout.
540      *
541      * @return the number of columns
542      */
543 
544     public int getNumColumn()
545     {
546         return crSpec[C].length;
547     }
548 
549     /**
550      * Gets the number of rows in this layout.
551      *
552      * @return the number of rows
553      */
554 
555     public int getNumRow()
556     {
557         return crSpec[R].length;
558     }
559 
560     /**
561      * Gets the horizontal gap between colunns.
562      *
563      * @return the horizontal gap in pixels
564      */
565 
566     public int getHGap()
567     {
568         return hGap;
569     }
570 
571     /**
572      * Gets the vertical gap between rows.
573      *
574      * @return the vertical gap in pixels
575      */
576 
577     public int getVGap()
578     {
579         return vGap;
580     }
581 
582     /**
583      * Sets the horizontal gap between colunns.
584      *
585      * @param hGap    the horizontal gap in pixels
586      */
587 
588     public void setHGap(int hGap)
589     {
590         if (hGap >= 0)
591             this.hGap = hGap;
592         else
593             throw new IllegalArgumentException("Parameter hGap must be non-negative.");
594     }
595 
596     /**
597      * Sets the vertical gap between rows.
598      *
599      * @param vGap    the horizontal gap in pixels
600      */
601 
602     public void setVGap(int vGap)
603     {
604         if (vGap >= 0)
605             this.vGap = vGap;
606         else
607             throw new IllegalArgumentException("Parameter vGap must be non-negative.");
608     }
609 
610     //******************************************************************************
611     //** Insertion/Deletion methods                                              ***
612     //******************************************************************************
613 
614     /**
615      * Inserts a column in this layout.  All components to the right of the
616      * insertion point are moved right one column.  The container will need to
617      * be laid out after this method returns.  See <code>setColumn</code>.
618      *
619      * @param i       zero-based index at which to insert the column
620      * @param size    size of the column to be inserted
621      */
622 
623     public void insertColumn(int i, double size)
624     {
625         insertCr(C, i, size);
626     }
627 
628     /**
629      * Inserts a row in this layout.  All components below the insertion point
630      * are moved down one row.  The container will need to be laid out after this
631      * method returns.  See <code>setRow</code>.
632      *
633      * @param i       zero-based index at which to insert the row
634      * @param size    size of the row to be inserted
635      */
636 
637     public void insertRow(int i, double size)
638     {
639         insertCr(R, i, size);
640     }
641 
642     /**
643      * Inserts a cr for the methods insertRow or insertColumn.
644      * 
645      * @param z       indicates row or column
646      * @param i       zero-based index at which to insert the cr
647      * @param size    size of cr being inserted
648      */
649 
650     public void insertCr(int z, int i, double size)
651     {
652         // Make sure position is valid
653         if ((i < 0) || (i > crSpec[z].length))
654             throw new IllegalArgumentException(
655                 "Parameter i is invalid.  i = " + i + ".  Valid range is [0, " + crSpec[z].length + "].");
656 
657         // Make sure row size is valid
658         if ((size < 0.0) && (size != FILL) && (size != PREFERRED) && (size != MINIMUM))
659         {
660             size = 0.0;
661         }
662 
663         // Copy crs
664         double cr[] = new double[crSpec[z].length + 1];
665         System.arraycopy(crSpec[z], 0, cr, 0, i);
666         System.arraycopy(crSpec[z], i, cr, i + 1, crSpec[z].length - i);
667 
668         // Insert cr
669         cr[i] = size;
670         crSpec[z] = cr;
671 
672         // Move all components that are below the new cr
673         ListIterator iterator = list.listIterator(0);
674 
675         while (iterator.hasNext())
676         {
677             // Get next entry
678             Entry entry = (Entry) iterator.next();
679 
680             // Is the first cr below the new cr
681             if (entry.cr1[z] >= i)
682                 // Move first cr
683                 entry.cr1[z]++;
684 
685             // Is the second cr below the new cr
686             if (entry.cr2[z] >= i)
687                 // Move second cr
688                 entry.cr2[z]++;
689         }
690 
691         // Indicate that the cell sizes are not known
692         dirty = true;
693     }
694 
695     /**
696      * Deletes a column in this layout.  All components to the right of the
697      * deletion point are moved left one column.  The container will need to
698      * be laid out after this method returns.  See <code>setColumn</code>.
699      *
700      * @param i    zero-based index of column to delete
701      */
702 
703     public void deleteColumn(int i)
704     {
705         deleteCr(C, i);
706     }
707 
708     /**
709      * Deletes a row in this layout.  All components below the deletion point are
710      * moved up one row.  The container will need to be laid out after this method
711      * returns.  See <code>setRow</code>.  There must be at least two rows in order
712      * to delete a row.
713      *
714      * @param i    zero-based index of row to delete
715      */
716 
717     public void deleteRow(int i)
718     {
719         deleteCr(R, i);
720     }
721 
722     /**
723      * Deletes a cr for the methods deleteRow or deleteColumn.
724      * 
725      * @param z       indicates row or column
726      * @param i       zero-based index of cr to delete
727      */
728 
729     protected void deleteCr(int z, int i)
730     {
731         // Make sure position is valid
732         if ((i < 0) || (i >= crSpec[z].length))
733             throw new IllegalArgumentException(
734                 "Parameter i is invalid.  i = "
735                     + i
736                     + ".  Valid range is [0, "
737                     + (crSpec[z].length - 1)
738                     + "].");
739 
740         // Copy rows
741         double cr[] = new double[crSpec[z].length - 1];
742         System.arraycopy(crSpec[z], 0, cr, 0, i);
743         System.arraycopy(crSpec[z], i + 1, cr, i, crSpec[z].length - i - 1);
744 
745         // Delete row
746         crSpec[z] = cr;
747 
748         // Move all components that are to below the row deleted
749         ListIterator iterator = list.listIterator(0);
750 
751         while (iterator.hasNext())
752         {
753             // Get next entry
754             Entry entry = (Entry) iterator.next();
755 
756             // Is the first row below the new row
757             if (entry.cr1[z] > i)
758                 // Move first row
759                 entry.cr1[z]--;
760 
761             // Is the second row below the new row
762             if (entry.cr2[z] > i)
763                 // Move second row
764                 entry.cr2[z]--;
765         }
766 
767         // Indicate that the cell sizes are not known
768         dirty = true;
769     }
770 
771     //******************************************************************************
772     //** Misc methods                                                            ***
773     //******************************************************************************
774 
775     /**
776      * Converts this TableLayout to a string.
777      *
778      * @return a string representing the columns and row sizes in the form
779      *         "{{col0, col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}}"
780      */
781 
782     public String toString()
783     {
784         int counter;
785 
786         String value = "TableLayout {{";
787 
788         if (crSpec[C].length > 0)
789         {
790             for (counter = 0; counter < crSpec[C].length - 1; counter++)
791                 value += crSpec[C][counter] + ", ";
792 
793             value += crSpec[C][crSpec[C].length - 1] + "}, {";
794         }
795         else
796             value += "}, {";
797 
798         if (crSpec[R].length > 0)
799         {
800             for (counter = 0; counter < crSpec[R].length - 1; counter++)
801                 value += crSpec[R][counter] + ", ";
802 
803             value += crSpec[R][crSpec[R].length - 1] + "}}";
804         }
805         else
806             value += "}}";
807 
808         return value;
809     }
810 
811     /**
812      * Determines whether or not there are any components with invalid constraints.
813      * An invalid constraint is one that references a non-existing row or column.
814      * For example, on a table with five rows, row -1 and row 5 are both invalid.
815      * Valid rows are 0 through 4, inclusively.
816      *
817      * @return an array of zero or more Component instances
818      */
819 
820     public Component[] getInvalidEntry()
821     {
822         LinkedList listInvalid = new LinkedList();
823         ListIterator iterator = list.listIterator(0);
824 
825         while (iterator.hasNext())
826         {
827             Entry entry = (Entry) iterator.next();
828 
829             if ((entry.cr1[R] < 0)
830                 || (entry.cr1[C] < 0)
831                 || (entry.cr2[R] >= crSpec[R].length)
832                 || (entry.cr2[C] >= crSpec[C].length))
833             {
834                 listInvalid.add(entry.component);
835             }
836         }
837 
838         return (Component[]) listInvalid.toArray(new Component[listInvalid.size()]);
839     }
840 
841     /**
842      * Gets a list of overlapping components.  Two components overlap if they cover
843      * at least one common cell.
844      *
845      * @return a list of zero or more Component instances
846      */
847 
848     public Component[] getOverlappingEntry()
849     {
850         LinkedList listOverlapping = new LinkedList();
851         int numEntry = list.size();
852         Entry entry[] = (Entry[]) list.toArray(new Entry[numEntry]);
853 
854         for (int knowUnique = 1; knowUnique < numEntry; knowUnique++)
855             for (int checking = knowUnique - 1; checking >= 0; checking--)
856                 if (((entry[checking].cr1[C] >= entry[knowUnique].cr1[C])
857                     && (entry[checking].cr1[C] <= entry[knowUnique].cr2[C])
858                     && (entry[checking].cr1[R] >= entry[knowUnique].cr1[R])
859                     && (entry[checking].cr1[R] <= entry[knowUnique].cr2[R]))
860                     || ((entry[checking].cr2[C] >= entry[knowUnique].cr1[C])
861                         && (entry[checking].cr2[C] <= entry[knowUnique].cr2[C])
862                         && (entry[checking].cr2[R] >= entry[knowUnique].cr1[R])
863                         && (entry[checking].cr2[R] <= entry[knowUnique].cr2[R])))
864                 {
865                     listOverlapping.add(entry[checking].component);
866                 }
867 
868         return (Component[]) listOverlapping.toArray(new Component[listOverlapping.size()]);
869     }
870 
871     //******************************************************************************
872     //** Calculation methods                                                     ***
873     //******************************************************************************
874 
875     /**
876      * Calculates the sizes of the rows and columns based on the absolute and
877      * relative sizes specified in <code>crSpec[R]</code> and <code>crSpec[C]</code>
878      * and the size of the container.  The result is stored in <code>crSize[R]</code>
879      * and <code>crSize[C]</code>.
880      *
881      * @param container    container using this TableLayout
882      */
883 
884     protected void calculateSize(Container container)
885     {
886         // Get the container's insets
887         Insets inset = container.getInsets();
888 
889         // Get the size of the container's available space
890         Dimension d = container.getSize();
891         int availableWidth = d.width - inset.left - inset.right;
892         int availableHeight = d.height - inset.top - inset.bottom;
893 
894         // Compensate for horiztonal and vertical gaps
895         if (crSpec[C].length > 0)
896             availableWidth -= hGap * (crSpec[C].length - 1);
897 
898         if (crSpec[R].length > 0)
899             availableHeight -= vGap * (crSpec[R].length - 1);
900 
901         // Create array to hold actual sizes in pixels
902         crSize[C] = new int[crSpec[C].length];
903         crSize[R] = new int[crSpec[R].length];
904 
905         // Assign absolute sizes
906         availableWidth = assignAbsoluteSize(C, availableWidth);
907         availableHeight = assignAbsoluteSize(R, availableHeight);
908 
909         // Assign preferred and minimum sizes
910         availableWidth = assignPrefMinSize(C, availableWidth, MINIMUM);
911         availableWidth = assignPrefMinSize(C, availableWidth, PREFERRED);
912         availableHeight = assignPrefMinSize(R, availableHeight, MINIMUM);
913         availableHeight = assignPrefMinSize(R, availableHeight, PREFERRED);
914 
915         // Assign relative sizes
916         availableWidth = assignRelativeSize(C, availableWidth);
917         availableHeight = assignRelativeSize(R, availableHeight);
918 
919         // Assign fill sizes
920         assignFillSize(C, availableWidth);
921         assignFillSize(R, availableHeight);
922 
923         // Calculate cr offsets for effeciency
924         calculateOffset(C, inset);
925         calculateOffset(R, inset);
926 
927         // Indicate that the size of the cells are known for the container's
928         // current size
929         dirty = false;
930         oldWidth = d.width;
931         oldHeight = d.height;
932     }
933 
934     /**
935      * Assigns absolute sizes.
936      *
937      * @param z                indicates row or column
938      * @param availableSize    amount of space available in the container
939      *
940      * @return the amount of space available after absolute crs have been assigned
941      *         sizes
942      */
943 
944     protected int assignAbsoluteSize(int z, int availableSize)
945     {
946         int numCr = crSpec[z].length;
947 
948         for (int counter = 0; counter < numCr; counter++)
949             if ((crSpec[z][counter] >= 1.0) || (crSpec[z][counter] == 0.0))
950             {
951                 crSize[z][counter] = (int) (crSpec[z][counter] + 0.5);
952                 availableSize -= crSize[z][counter];
953             }
954 
955         return availableSize;
956     }
957 
958     /**
959      * Assigns relative sizes.
960      *
961      * @param z                indicates row or column
962      * @param availableSize    amount of space available in the container
963      *
964      * @return the amount of space available after relative crs have been assigned
965      *         sizes
966      */
967 
968     protected int assignRelativeSize(int z, int availableSize)
969     {
970         int relativeSize = (availableSize < 0) ? 0 : availableSize;
971         int numCr = crSpec[z].length;
972 
973         for (int counter = 0; counter < numCr; counter++)
974             if ((crSpec[z][counter] > 0.0) && (crSpec[z][counter] < 1.0))
975             {
976                 crSize[z][counter] = (int) (crSpec[z][counter] * relativeSize + 0.5);
977 
978                 availableSize -= crSize[z][counter];
979             }
980 
981         return availableSize;
982     }
983 
984     /**
985      * Assigns FILL sizes.
986      *
987      * @param z                indicates row or column
988      * @param availableSize    amount of space available in the container
989      */
990 
991     protected void assignFillSize(int z, int availableSize)
992     {
993         // Skip if there is no more space to allocate
994         if (availableSize <= 0)
995             return;
996 
997         // Count the number of "fill" cells
998         int numFillSize = 0;
999         int numCr = crSpec[z].length;
1000
1001        for (int counter = 0; counter < numCr; counter++)
1002            if (crSpec[z][counter] == FILL)
1003                numFillSize++;
1004
1005        // If numFillSize is zero, the if statement below will always evaluate to
1006        // false and the division will not occur.
1007
1008        // If there are more than one "fill" cell, slack may occur due to rounding
1009        // errors
1010        int slackSize = availableSize;
1011
1012        // Assign "fill" cells equal amounts of the remaining space
1013        for (int counter = 0; counter < numCr; counter++)
1014            if (crSpec[z][counter] == FILL)
1015            {
1016                crSize[z][counter] = availableSize / numFillSize;
1017                slackSize -= crSize[z][counter];
1018            }
1019
1020        // Assign one pixel of slack to each FILL cr, starting at the last one,
1021        // until all slack has been consumed
1022        for (int counter = numCr - 1;(counter >= 0) && (slackSize > 0); counter--)
1023        {
1024            if (crSpec[z][counter] == FILL)
1025            {
1026                crSize[z][counter]++;
1027                slackSize--;
1028            }
1029        }
1030    }
1031
1032    /**
1033     * Calculates the offset of each cr.
1034     *
1035     * @param z    indicates row or column
1036     * @param inset
1037     */
1038
1039    protected void calculateOffset(int z, Insets inset)
1040    {
1041        int numCr = crSpec[z].length;
1042
1043        crOffset[z] = new int[numCr + 1];
1044        crOffset[z][0] = (z == C) ? inset.left : inset.top;
1045
1046        for (int counter = 0; counter < numCr; counter++)
1047            crOffset[z][counter + 1] = crOffset[z][counter] + crSize[z][counter];
1048    }
1049
1050    /**
1051     * Assigned widths to preferred and minimum size columns and rows.  This
1052     * reduces the available width and height.  Minimum widths/heights must be
1053     * calculated first because they affect preferred widths/heights, but not vice
1054     * versa.  The end result is that any component contained wholly or partly in
1055     * a column/row of minimum/preferred width will get at least its
1056     * minimum/preferred width, respectively.
1057     *
1058     * @param z                indicates row or column
1059     * @param availableSize    amount of space available in the container
1060     * @param typeOfSize       indicates preferred or minimum
1061     *
1062     * @return the amount of space available after absolute crs have been assigned
1063     *         sizes
1064     */
1065
1066    protected int assignPrefMinSize(int z, int availableSize, double typeOfSize)
1067    {
1068        // Get variables referring to columns or rows (crs)
1069        int numCr = crSpec[z].length;
1070
1071        // Address every cr
1072        for (int counter = 0; counter < numCr; counter++)
1073            // Is the current cr a preferred/minimum (based on typeOfSize) size
1074            if (crSpec[z][counter] == typeOfSize)
1075            {
1076                // Assume a maximum width of zero
1077                int maxSize = 0;
1078
1079                // Find maximum preferred/min width of all components completely
1080                // or partially contained within this cr
1081                ListIterator iterator = list.listIterator(0);
1082
1083                nextComponent : while (iterator.hasNext())
1084                {
1085                    Entry entry = (Entry) iterator.next();
1086
1087                    // Skip invalid entries
1088                    if ((entry.cr1[z] < 0) || (entry.cr2[z] >= numCr))
1089                        continue nextComponent;
1090
1091                    // Find the maximum desired size of this cr based on all crs
1092                    // the current component occupies
1093                    if ((entry.cr1[z] <= counter) && (entry.cr2[z] >= counter))
1094                    {
1095                        // Setup size and number of adjustable crs
1096                        Dimension p =
1097                            (typeOfSize == PREFERRED)
1098                                ? entry.component.getPreferredSize()
1099                                : entry.component.getMinimumSize();
1100
1101                        int size = (p == null) ? 0 : ((z == C) ? p.width : p.height);
1102                        int numAdjustable = 0;
1103
1104                        // Calculate for preferred size
1105                        if (typeOfSize == PREFERRED)
1106                            // Consider all crs this component occupies
1107                            for (int entryCr = entry.cr1[z]; entryCr <= entry.cr2[z]; entryCr++)
1108                            {
1109                                // Subtract absolute, relative, and minumum cr
1110                                // sizes, which have already been calculated
1111                                if ((crSpec[z][entryCr] >= 0.0) || (crSpec[z][entryCr] == MINIMUM))
1112                                {
1113                                    size -= crSize[z][entryCr];
1114                                }
1115                                // Count preferred/min width columns
1116                                else if (crSpec[z][entryCr] == PREFERRED)
1117                                    numAdjustable++;
1118                                // Skip any component that occupies a fill cr
1119                                // because the fill should fulfill the size
1120                                // requirements
1121                                else if (crSpec[z][entryCr] == FILL)
1122                                    continue nextComponent;
1123                            }
1124                        // Calculate for minimum size
1125                        else
1126                            // Consider all crs this component occupies
1127                            for (int entryCr = entry.cr1[z]; entryCr <= entry.cr2[z]; entryCr++)
1128                            {
1129                                // Subtract absolute and relative cr sizes, which
1130                                // have already been calculated
1131                                if (crSpec[z][entryCr] >= 0.0)
1132                                    size -= crSize[z][entryCr];
1133                                // Count preferred/min width columns
1134                                else if (
1135                                    (crSpec[z][entryCr] == PREFERRED) || (crSpec[z][entryCr] == MINIMUM))
1136                                {
1137                                    numAdjustable++;
1138                                }
1139                                // Skip any component that occupies a fill cr
1140                                // because the fill should fulfill the size
1141                                // requirements
1142                                else if (crSpec[z][entryCr] == FILL)
1143                                    continue nextComponent;
1144                            }
1145
1146                        // Divide the size evenly among the adjustable crs
1147                        size = (int) Math.ceil(size / (double) numAdjustable);
1148
1149                        // Take the maximumn size
1150                        if (maxSize < size)
1151                            maxSize = size;
1152                    }
1153                }
1154
1155                // Assign preferred size
1156                crSize[z][counter] = maxSize;
1157
1158                // Reduce available size
1159                availableSize -= maxSize;
1160            }
1161
1162        return availableSize;
1163    }
1164
1165    //******************************************************************************
1166    //** java.awt.event.LayoutManager methods                                    ***
1167    //******************************************************************************
1168
1169    /**
1170     * To lay out the specified container using this layout.  This method reshapes
1171     * the components in the specified target container in order to satisfy the
1172     * constraints of all components.
1173     *
1174     * <p>User code should not have to call this method directly.</p>
1175     *
1176     * @param container    container being served by this layout manager
1177     */
1178
1179    public void layoutContainer(Container container)
1180    {
1181        // Calculate sizes if container has changed size or components were added
1182        Dimension d = container.getSize();
1183
1184        if (dirty || (d.width != oldWidth) || (d.height != oldHeight))
1185            calculateSize(container);
1186
1187        // Get components
1188        Component component[] = container.getComponents();
1189
1190        // Layout components
1191        for (int counter = 0; counter < component.length; counter++)
1192        {
1193            try
1194            {
1195                // Get the entry for the next component
1196                ListIterator iterator = list.listIterator(0);
1197                Entry entry = null;
1198
1199                while (iterator.hasNext())
1200                {
1201                    entry = (Entry) iterator.next();
1202
1203                    if (entry.component == component[counter])
1204                        break;
1205                    else
1206                        entry = null;
1207                }
1208
1209                // Skip any components that have not been place in a specific cell,
1210                // setting the skip component's bounds to zero
1211                if (entry == null)
1212                {
1213                    component[counter].setBounds(0, 0, 0, 0);
1214                    continue;
1215                }
1216
1217                // The following block of code has been optimized so that the
1218                // preferred size of the component is only obtained if it is
1219                // needed.  There are components in which the getPreferredSize
1220                // method is extremely expensive, such as data driven controls
1221                // with a large amount of data.
1222
1223                // Get the preferred size of the component
1224                int preferredWidth = 0;
1225                int preferredHeight = 0;
1226
1227                if ((entry.alignment[C] != FULL) || (entry.alignment[R] != FULL))
1228                {
1229                    Dimension preferredSize = component[counter].getPreferredSize();
1230
1231                    preferredWidth = preferredSize.width;
1232                    preferredHeight = preferredSize.height;
1233                }
1234
1235                // Calculate the coordinates and size of the component
1236                int value[] = calculateSizeAndOffset(entry, preferredWidth, true);
1237                int x = value[0];
1238                int w = value[1];
1239                value = calculateSizeAndOffset(entry, preferredHeight, false);
1240                int y = value[0];
1241                int h = value[1];
1242
1243                // Move and resize component
1244                component[counter].setBounds(x, y, w, h);
1245            }
1246            catch (Exception error)
1247            {
1248                // If any error occurs, set the bounds of this component to zero
1249                // and continue
1250                component[counter].setBounds(0, 0, 0, 0);
1251                continue;
1252            }
1253        }
1254    }
1255
1256    /**
1257     * Calculates the vertical/horizontal offset and size of a component.
1258     *
1259     * @param entry    entry containing component and contraints
1260     * @param preferredSize    previously calculated preferred width/height of
1261     *                         component
1262     * @param isColumn         if true, this method is being called to calculate
1263     *                         the offset/size of a column.  if false,... of a row.
1264     *
1265     * @return an array, a, of two integers such that a[0] is the offset and
1266     *         a[1] is the size
1267     */
1268
1269    protected int[] calculateSizeAndOffset(Entry entry, int preferredSize, boolean isColumn)
1270    {
1271        // Get references to cr properties
1272        int lCrOffset[] = isColumn ? this.crOffset[C] : this.crOffset[R];
1273        int entryAlignment = isColumn ? entry.alignment[C] : entry.alignment[R];
1274
1275        // Determine cell set size
1276        int cellSetSize =
1277            isColumn
1278                ? lCrOffset[entry.cr2[C] + 1] - lCrOffset[entry.cr1[C]]
1279                : lCrOffset[entry.cr2[R] + 1] - lCrOffset[entry.cr1[R]];
1280
1281        // Determine the size of the component
1282        int size;
1283
1284        if ((entryAlignment == FULL) || (cellSetSize < preferredSize))
1285            size = cellSetSize;
1286        else
1287            size = preferredSize;
1288
1289        // Determine offset
1290        int offset;
1291
1292        switch (entryAlignment)
1293        {
1294            case LEFT : // Align left/top side along left edge of cell
1295                offset = lCrOffset[isColumn ? entry.cr1[C] : entry.cr1[R]];
1296                break;
1297
1298            case RIGHT : // Align right/bottom side along right edge of cell
1299                offset = lCrOffset[(isColumn ? entry.cr2[C] : entry.cr2[R]) + 1] - size;
1300                break;
1301
1302            case CENTER : // Center justify component
1303                offset = lCrOffset[isColumn ? entry.cr1[C] : entry.cr1[R]] + ((cellSetSize - size) >> 1);
1304                break;
1305
1306            case FULL : // Align left/top side along left/top edge of cell
1307                offset = lCrOffset[isColumn ? entry.cr1[C] : entry.cr1[R]];
1308                break;
1309
1310            default : // This is a never should happen case, but just in case
1311                offset = 0;
1312        }
1313
1314        // Compensate for gaps
1315        if (isColumn)
1316        {
1317            offset += hGap * entry.cr1[C];
1318            size += hGap * (entry.cr2[C] - entry.cr1[C]);
1319        }
1320        else
1321        {
1322            offset += vGap * entry.cr1[R];
1323            size += hGap * (entry.cr2[R] - entry.cr1[R]);
1324        }
1325
1326        // Package return values
1327        int value[] = { offset, size };
1328        return value;
1329    }
1330
1331    /**
1332     * Determines the preferred size of the container argument using this layout.
1333     * The preferred size is the smallest size that, if used for the container's
1334     * size, will ensure that all components are at least as large as their
1335     * preferred size.  This method cannot guarantee that all components will be
1336     * their preferred size.  For example, if component A and component B are each
1337     * allocate half of the container's width and component A wants to be 10 pixels
1338     * wide while component B wants to be 100 pixels wide, they cannot both be
1339     * accommodated.  Since in general components rather be larger than their
1340     * preferred size instead of smaller, component B's request will be fulfilled.
1341     * The preferred size of the container would be 200 pixels.
1342     *
1343     * @param container    container being served by this layout manager
1344     *
1345     * @return a dimension indicating the container's preferred size
1346     */
1347
1348    public Dimension preferredLayoutSize(Container container)
1349    {
1350        return calculateLayoutSize(container, PREFERRED);
1351    }
1352
1353    /**
1354     * Determines the minimum size of the container argument using this layout.
1355     * The minimum size is the smallest size that, if used for the container's
1356     * size, will ensure that all components are at least as large as their
1357     * minimum size.  This method cannot guarantee that all components will be
1358     * their minimum size.  For example, if component A and component B are each
1359     * allocate half of the container's width and component A wants to be 10 pixels
1360     * wide while component B wants to be 100 pixels wide, they cannot both be
1361     * accommodated.  Since in general components rather be larger than their
1362     * minimum size instead of smaller, component B's request will be fulfilled.
1363     * The minimum size of the container would be 200 pixels.
1364     *
1365     * @param container    container being served by this layout manager
1366     *
1367     * @return a dimension indicating the container's minimum size
1368     */
1369
1370    public Dimension minimumLayoutSize(Container container)
1371    {
1372        return calculateLayoutSize(container, MINIMUM);
1373    }
1374
1375    /**
1376     * Calculates the preferred or minimum size for the methods preferredLayoutSize
1377     * and minimumLayoutSize.
1378     * 
1379     * @param container     container whose size is being calculated
1380     * @param typeOfSize    indicates preferred or minimum
1381     * 
1382     * @return a dimension indicating the container's preferred or minimum size
1383     */
1384
1385    protected Dimension calculateLayoutSize(Container container, double typeOfSize)
1386    {
1387        //  Get preferred/minimum sizes
1388        Entry entryList[] = (Entry[]) list.toArray(new Entry[list.size()]);
1389        int numEntry = entryList.length;
1390        Dimension prefMinSize[] = new Dimension[numEntry];
1391
1392        for (int i = 0; i < numEntry; i++)
1393            prefMinSize[i] =
1394                (typeOfSize == PREFERRED)
1395                    ? entryList[i].component.getPreferredSize()
1396                    : entryList[i].component.getMinimumSize();
1397
1398        // Calculate sizes
1399        int width = calculateLayoutSize(container, C, typeOfSize, entryList, prefMinSize);
1400
1401        int height = calculateLayoutSize(container, R, typeOfSize, entryList, prefMinSize);
1402
1403        // Compensate for container's insets
1404        Insets inset = container.getInsets();
1405        width += inset.left + inset.right;
1406        height += inset.top + inset.bottom;
1407
1408        return new Dimension(width, height);
1409    }
1410
1411    /**
1412     * Calculates the preferred or minimum size for the method
1413     * calculateLayoutSize(Container container, double typeOfSize).  This method
1414     * is passed the preferred/minimum sizes of the components so that the
1415     * potentially expensive methods getPreferredSize()/getMinimumSize() are not
1416     * called twice for the same component.
1417     * 
1418     * @param container      container whose size is being calculated
1419     * @param z
1420     * @param typeOfSize     indicates preferred or minimum
1421     * @param entryList      list of Entry objects
1422     * @param prefMinSize    list of preferred or minimum sizes
1423     * 
1424     * @return a dimension indicating the container's preferred or minimum size
1425     */
1426
1427    protected int calculateLayoutSize(
1428        Container container,
1429        int z,
1430        double typeOfSize,
1431        Entry entryList[],
1432        Dimension prefMinSize[])
1433    {
1434        Dimension size; // Preferred/minimum size of current component
1435        int scaledSize = 0; // Preferred/minimum size of scaled components
1436        int temp; // Temporary variable used to compare sizes
1437        int counter; // Counting variable
1438
1439        // Get number of crs
1440        int numCr = crSpec[z].length;
1441
1442        // Determine percentage of space allocated to fill components.  This is
1443        // one minus the sum of all scalable components.
1444        double fillSizeRatio = 1.0;
1445        int numFillSize = 0;
1446
1447        for (counter = 0; counter < numCr; counter++)
1448            if ((crSpec[z][counter] > 0.0) && (crSpec[z][counter] < 1.0))
1449                fillSizeRatio -= crSpec[z][counter];
1450            else if (crSpec[z][counter] == FILL)
1451                numFillSize++;
1452
1453        // Adjust fill ratios to reflect number of fill rows/columns
1454        if (numFillSize > 1)
1455            fillSizeRatio /= numFillSize;
1456
1457        // Cap fill ratio bottoms to 0.0
1458        if (fillSizeRatio < 0.0)
1459            fillSizeRatio = 0.0;
1460
1461        // Create array to hold actual sizes in pixels
1462        crSize[z] = new int[numCr];
1463
1464        // Calculate preferred/minimum cr sizes
1465        assignPrefMinSize(z, 0, typeOfSize);
1466
1467        int crPrefMin[] = new int[numCr];
1468
1469        for (counter = 0; counter < numCr; counter++)
1470            if ((crSpec[z][counter] == PREFERRED) || (crSpec[z][counter] == MINIMUM))
1471            {
1472                crPrefMin[counter] = crSize[z][counter];
1473            }
1474
1475        // Find maximum preferred/minimum size of all scaled components
1476        int numColumn = crSpec[C].length;
1477        int numRow = crSpec[R].length;
1478        int numEntry = entryList.length;
1479
1480        for (int entryCounter = 0; entryCounter < numEntry; entryCounter++)
1481        {
1482            // Get next entry
1483            Entry entry = entryList[entryCounter];
1484
1485            // Make sure entry is in valid rows and columns
1486            if ((entry.cr1[C] < 0)
1487                || (entry.cr1[C] >= numColumn)
1488                || (entry.cr2[C] >= numColumn)
1489                || (entry.cr1[R] < 0)
1490                || (entry.cr1[R] >= numRow)
1491                || (entry.cr2[R] >= numRow))
1492            {
1493                // Skip the bad component
1494                continue;
1495            }
1496
1497            // Get preferred/minimum size of current component
1498            size = prefMinSize[entryCounter];
1499
1500            //----------------------------------------------------------------------
1501
1502            // Calculate portion of component that is not absolutely sized
1503            int scalableSize = (z == C) ? size.width : size.height;
1504
1505            for (counter = entry.cr1[z]; counter <= entry.cr2[z]; counter++)
1506                if (crSpec[z][counter] >= 1.0)
1507                    scalableSize -= crSpec[z][counter];
1508                else if ((crSpec[z][counter] == PREFERRED) || (crSpec[z][counter] == MINIMUM))
1509                {
1510                    scalableSize -= crPrefMin[counter];
1511                }
1512
1513            //----------------------------------------------------------------------
1514
1515            // Determine total percentage of scalable space that the component
1516            // occupies by adding the relative columns and the fill columns
1517            double relativeSize = 0.0;
1518
1519            for (counter = entry.cr1[z]; counter <= entry.cr2[z]; counter++)
1520            {
1521                // Cr is scaled
1522                if ((crSpec[z][counter] > 0.0) && (crSpec[z][counter] < 1.0))
1523                    // Add scaled size to relativeWidth
1524                    relativeSize += crSpec[z][counter];
1525                // Cr is fill
1526                else if ((crSpec[z][counter] == FILL) && (fillSizeRatio != 0.0))
1527                    // Add fill size to relativeWidth
1528                    relativeSize += fillSizeRatio;
1529            }
1530
1531            // Determine the total scaled size as estimated by this component
1532            if (relativeSize == 0)
1533                temp = 0;
1534            else
1535                temp = (int) (scalableSize / relativeSize + 0.5);
1536
1537            //----------------------------------------------------------------------
1538
1539            // If the container needs to be bigger, make it so
1540            if (scaledSize < temp)
1541                scaledSize = temp;
1542        }
1543
1544        // totalSize is the scaledSize plus the sum of all absolute sizes and all
1545        // preferred sizes
1546        int totalSize = scaledSize;
1547
1548        for (counter = 0; counter < numCr; counter++)
1549            // Is the current cr an absolute size
1550            if (crSpec[z][counter] >= 1.0)
1551                totalSize += (int) (crSpec[z][counter] + 0.5);
1552        // Is the current cr a preferred/minimum size
1553        else if ((crSpec[z][counter] == PREFERRED) || (crSpec[z][counter] == MINIMUM))
1554        {
1555            // Add preferred/minimum width
1556            totalSize += crPrefMin[counter];
1557        }
1558
1559        // Compensate for horizontal and vertical gap
1560        if (numCr > 0)
1561            totalSize += ((z == C) ? hGap : vGap) * (numCr - 1);
1562
1563        return totalSize;
1564    }
1565
1566    /**
1567     * Adds the specified component with the specified name to the layout.
1568     *
1569     * @param name         indicates entry's position and anchor
1570     * @param component    component to add
1571     */
1572
1573    public void addLayoutComponent(String name, Component component)
1574    {
1575        addLayoutComponen