Source Code Cross Referenced for TableLayout.java in  » Content-Management-System » contelligent » de » finix » contelligent » client » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » contelligent » de.finix.contelligent.client.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2006 C:1 Financial Services GmbH
0003:         *
0004:         * This software is free software; you can redistribute it and/or
0005:         * modify it under the terms of the GNU Lesser General Public
0006:         * License Version 2.1, as published by the Free Software Foundation.
0007:         *
0008:         * This software is distributed in the hope that it will be useful,
0009:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0010:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0011:         * Lesser General Public License for more details.
0012:         *
0013:         * You should have received a copy of the GNU Lesser General Public
0014:         * License along with this library; if not, write to the Free Software
0015:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
0016:         */
0017:
0018:        package de.finix.contelligent.client.util;
0019:
0020:        import java.awt.Color;
0021:        import java.awt.Component;
0022:        import java.awt.Container;
0023:        import java.awt.Dimension;
0024:        import java.awt.Graphics;
0025:        import java.awt.Insets;
0026:        import java.util.HashMap;
0027:        import java.util.LinkedList;
0028:        import java.util.ListIterator;
0029:        import java.util.Map;
0030:        import java.util.StringTokenizer;
0031:
0032:        /**
0033:         * TableLayout is a layout manager that arranges components in rows and columns
0034:         * like a spreadsheet. TableLayout allows each row or column to be a different
0035:         * size. A row or column can be given an absolute size in pixels, a percentage
0036:         * of the available space, or it can grow and shrink to fill the remaining space
0037:         * after other rows and columns have been resized.
0038:         * 
0039:         * <p>
0040:         * Using spreadsheet terminology, a cell is the intersection of a row and
0041:         * column. Cells have finite, non-negative sizes measured in pixels. The
0042:         * dimensions of a cell depend solely upon the dimensions of its row and column.
0043:         * </p>
0044:         * 
0045:         * <p>
0046:         * A component occupies a rectangular group of one or more cells. If the
0047:         * component occupies more than one cell, the component is resized to fit
0048:         * perfectly in the rectangular region of cells. If the component occupies a
0049:         * single cell, it can be aligned in four ways within that cell.
0050:         * </p>
0051:         * 
0052:         * <p>
0053:         * A single cell component can be stretched horizontally to fit the cell (full
0054:         * justification), or it can be placed in the center of the cell. The component
0055:         * could also be left justified or right justified. Similarly, the component can
0056:         * be full, center, top, or bottom justified in the vertical.
0057:         * </p>
0058:         * 
0059:         * <pre>
0060:         *  public static void main (String args[])
0061:         *  {
0062:         *      // Create a frame
0063:         *      Frame frame = new Frame(&quot;Example of TableLayout&quot;);
0064:         *      frame.setBounds (100, 100, 300, 300);
0065:         *  &lt;spc&gt;
0066:         *      // Create a TableLayout for the frame
0067:         *      double border = 10;
0068:         *      double size[][] =
0069:         *          {{border, 0.10, 20, TableLayout.FILL, 20, 0.20, border},  // Columns
0070:         *           {border, 0.20, 20, TableLayout.FILL, 20, 0.20, border}}; // Rows
0071:         *  &lt;spc&gt;
0072:         *      frame.setLayout (new TableLayout(size));
0073:         *  &lt;spc&gt;
0074:         *      // Create some buttons
0075:         *      String label[] = {&quot;Top&quot;, &quot;Bottom&quot;, &quot;Left&quot;, &quot;Right&quot;, &quot;Center&quot;, &quot;Overlap&quot;};
0076:         *      Button button[] = new Button[label.length];
0077:         *  &lt;spc&gt;
0078:         *      for (int i = 0; i &lt; label.length; i++)
0079:         *          button[i] = new Button(label[i]);
0080:         *  &lt;spc&gt;
0081:         *      // Add buttons
0082:         *      frame.add (button[0], &quot;1, 1, 5, 1&quot;); // Top
0083:         *      frame.add (button[1], &quot;1, 5, 5, 5&quot;); // Bottom
0084:         *      frame.add (button[2], &quot;1, 3      &quot;); // Left
0085:         *      frame.add (button[3], &quot;5, 3      &quot;); // Right
0086:         *      frame.add (button[4], &quot;3, 3, c, c&quot;); // Center
0087:         *      frame.add (button[5], &quot;3, 3, 3, 5&quot;); // Overlap
0088:         *  &lt;spc&gt;
0089:         *      // Allow user to close the window to terminate the program
0090:         *      frame.addWindowListener
0091:         *          (new WindowListener()
0092:         *              {
0093:         *                  public void windowClosing (WindowEvent e)
0094:         *                  {
0095:         *                      System.exit (0);
0096:         *                  }
0097:         *  &lt;spc&gt;
0098:         *                  public void windowOpened (WindowEvent e) {}
0099:         *                  public void windowClosed (WindowEvent e) {}
0100:         *                  public void windowIconified (WindowEvent e) {}
0101:         *                  public void windowDeiconified (WindowEvent e) {}
0102:         *                  public void windowActivated (WindowEvent e) {}
0103:         *                  public void windowDeactivated (WindowEvent e) {}
0104:         *              }
0105:         *          );
0106:         *  &lt;spc&gt;
0107:         *      // Show frame
0108:         *      frame.show();
0109:         *  }
0110:         * </pre>
0111:         */
0112:
0113:        public class TableLayout implements  java.awt.LayoutManager2,
0114:                java.io.Serializable, TableLayoutConstants {
0115:
0116:            /** Default row/column size */
0117:            protected static final double defaultSize[][] = { {}, {} };
0118:
0119:            /** Widths of columns expressed in absolute and relative terms */
0120:            protected double columnSpec[];
0121:
0122:            /** Heights of rows expressed in absolute and relative terms */
0123:            protected double rowSpec[];
0124:
0125:            /** Widths of columns in pixels */
0126:            protected int columnSize[];
0127:
0128:            /** Heights of rows in pixels */
0129:            protected int rowSize[];
0130:
0131:            /**
0132:             * Offsets of columns in pixels. The left boarder of column n is at
0133:             * columnOffset[n] and the right boarder is at columnOffset[n + 1] for all
0134:             * columns including the last one. columnOffset.length = columnSize.length +
0135:             * 1
0136:             */
0137:            protected int columnOffset[];
0138:
0139:            /**
0140:             * Offsets of rows in pixels. The left boarder of row n is at rowOffset[n]
0141:             * and the right boarder is at rowOffset[n + 1] for all rows including the
0142:             * last one. rowOffset.length = rowSize.length + 1
0143:             */
0144:            protected int rowOffset[];
0145:
0146:            // Olli Z.: map name -> number, String -> String
0147:            protected Map columnOrRowName = null;
0148:
0149:            /** List of components and their sizes */
0150:            protected LinkedList list;
0151:
0152:            /**
0153:             * Indicates whether or not the size of the cells are known for the last
0154:             * known size of the container. If dirty is true or the container has been
0155:             * resized, the cell sizes must be recalculated using calculateSize.
0156:             */
0157:            protected boolean dirty;
0158:
0159:            /** Previous known width of the container */
0160:            protected int oldWidth;
0161:
0162:            /** Previous known height of the container */
0163:            protected int oldHeight;
0164:
0165:            // ******************************************************************************
0166:            // ** Constructors ***
0167:            // ******************************************************************************
0168:
0169:            /**
0170:             * Constructs an instance of TableLayout. This TableLayout will have one row
0171:             * and one column.
0172:             */
0173:
0174:            public TableLayout() {
0175:                this (defaultSize);
0176:            }
0177:
0178:            /**
0179:             * Constructs an instance of TableLayout.
0180:             * 
0181:             * @param size
0182:             *            widths of columns and heights of rows in the format, {{col0,
0183:             *            col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}} If this
0184:             *            parameter is invalid, the TableLayout will have exactly one
0185:             *            row and one column.
0186:             */
0187:            public TableLayout(String declaration[][]) {
0188:                if ((declaration != null) && (declaration.length == 2)) {
0189:
0190:                    int colSize = declaration[0].length;
0191:                    double[] colSizes = new double[colSize];
0192:                    columnOrRowName = new HashMap();
0193:
0194:                    for (int c = 0; c < colSize; c++) {
0195:                        String col = declaration[0][c];
0196:                        // this is a named column
0197:                        int eqPos;
0198:                        double info;
0199:                        if ((eqPos = col.indexOf('=')) != -1) {
0200:                            String pureInfo = col.substring(0, eqPos);
0201:                            String name = col
0202:                                    .substring(eqPos + 1, col.length());
0203:                            info = makeInfo(pureInfo);
0204:                            columnOrRowName.put(name, String.valueOf(c));
0205:                        } else {
0206:                            info = makeInfo(col);
0207:                        }
0208:                        colSizes[c] = info;
0209:                    }
0210:
0211:                    int rowSize = declaration[1].length;
0212:                    double[] rowSizes = new double[rowSize];
0213:
0214:                    for (int r = 0; r < rowSize; r++) {
0215:                        String row = declaration[1][r];
0216:                        // this is a named column
0217:                        int eqPos;
0218:                        double info;
0219:                        if ((eqPos = row.indexOf('=')) != -1) {
0220:                            String pureInfo = row.substring(0, eqPos);
0221:                            String name = row
0222:                                    .substring(eqPos + 1, row.length());
0223:                            info = makeInfo(pureInfo);
0224:                            columnOrRowName.put(name, String.valueOf(r));
0225:                        } else {
0226:                            info = makeInfo(row);
0227:                        }
0228:                        rowSizes[r] = info;
0229:                    }
0230:                    init(new double[][] { colSizes, rowSizes });
0231:                } else {
0232:                    init(null);
0233:                }
0234:            }
0235:
0236:            private double makeInfo(String pureInfo) {
0237:                if (pureInfo.equals("FILL")
0238:                        || pureInfo.equals("TableLayout.FILL")) {
0239:                    return FILL;
0240:                } else if (pureInfo.equals("PREFERRED")
0241:                        || pureInfo.equals("TableLayout.PREFERRED")) {
0242:                    return PREFERRED;
0243:                } else if (pureInfo.equals("MINIMUM")
0244:                        || pureInfo.equals("TableLayout.MINIMUM")) {
0245:                    return MINIMUM;
0246:                } else {
0247:                    try {
0248:                        double d = Double.valueOf(pureInfo).doubleValue();
0249:                        return d;
0250:                    } catch (NumberFormatException nfe) {
0251:                        // will evantually become 0.0 in init
0252:                        return -1;
0253:                    }
0254:                }
0255:            }
0256:
0257:            /**
0258:             * Constructs an instance of TableLayout.
0259:             * 
0260:             * @param size
0261:             *            widths of columns and heights of rows in the format, {{col0,
0262:             *            col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}} If this
0263:             *            parameter is invalid, the TableLayout will have exactly one
0264:             *            row and one column.
0265:             */
0266:            public TableLayout(double size[][]) {
0267:                init(size);
0268:            }
0269:
0270:            private void init(double size[][]) {
0271:                // Make sure rows and columns and nothing else is specified
0272:                if ((size != null) && (size.length == 2)) {
0273:                    // Get the rows and columns
0274:                    double tempCol[] = size[0];
0275:                    double tempRow[] = size[1];
0276:
0277:                    // Create new rows and columns
0278:                    columnSpec = new double[tempCol.length];
0279:                    rowSpec = new double[tempRow.length];
0280:
0281:                    // Copy rows and columns
0282:                    System.arraycopy(tempCol, 0, columnSpec, 0,
0283:                            columnSpec.length);
0284:                    System.arraycopy(tempRow, 0, rowSpec, 0, rowSpec.length);
0285:
0286:                    // Make sure rows and columns are valid
0287:                    for (int counter = 0; counter < columnSpec.length; counter++)
0288:                        if ((columnSpec[counter] < 0.0)
0289:                                && (columnSpec[counter] != FILL)
0290:                                && (columnSpec[counter] != PREFERRED)
0291:                                && (columnSpec[counter] != MINIMUM)) {
0292:                            columnSpec[counter] = 0.0;
0293:                        }
0294:
0295:                    for (int counter = 0; counter < rowSpec.length; counter++)
0296:                        if ((rowSpec[counter] < 0.0)
0297:                                && (rowSpec[counter] != FILL)
0298:                                && (rowSpec[counter] != PREFERRED)
0299:                                && (rowSpec[counter] != MINIMUM)) {
0300:                            rowSpec[counter] = 0.0;
0301:                        }
0302:                } else {
0303:                    double tempCol[] = { FILL };
0304:                    double tempRow[] = { FILL };
0305:
0306:                    setColumn(tempCol);
0307:                    setRow(tempRow);
0308:                }
0309:
0310:                // Create an empty list of components
0311:                list = new LinkedList();
0312:
0313:                // Indicate that the cell sizes are not known
0314:                dirty = true;
0315:            }
0316:
0317:            // ******************************************************************************
0318:            // ** Get/Set methods ***
0319:            // ******************************************************************************
0320:
0321:            /**
0322:             * Gets the constraints of a given component.
0323:             * 
0324:             * @param component
0325:             *            desired component
0326:             * 
0327:             * @return If the given component is found, the constraints associated with
0328:             *         that component. If the given component is null or is not found,
0329:             *         null is returned.
0330:             */
0331:
0332:            public TableLayoutConstraints getConstraints(Component component) {
0333:                ListIterator iterator = list.listIterator(0);
0334:
0335:                while (iterator.hasNext()) {
0336:                    Entry entry = (Entry) iterator.next();
0337:
0338:                    if (entry.component == component)
0339:                        return new TableLayoutConstraints(entry.col1,
0340:                                entry.row1, entry.col2, entry.row2,
0341:                                entry.hAlign, entry.vAlign);
0342:                }
0343:
0344:                return null;
0345:            }
0346:
0347:            /**
0348:             * Sets the constraints of a given component.
0349:             * 
0350:             * @param component
0351:             *            desired component. This parameter cannot be null.
0352:             * @param constraint
0353:             *            new set of constraints. This parameter cannot be null.
0354:             * 
0355:             * @return If the given component is found, the constraints associated with
0356:             *         that component. If the given component is null or is not found,
0357:             *         null is returned.
0358:             */
0359:
0360:            public void setConstraints(Component component,
0361:                    TableLayoutConstraints constraint) {
0362:                // Check parameters
0363:                if (component == null)
0364:                    throw new IllegalArgumentException(
0365:                            "Parameter component cannot be null.");
0366:                else if (constraint == null)
0367:                    throw new IllegalArgumentException(
0368:                            "Parameter constraint cannot be null.");
0369:
0370:                // Find and update constraints for the given component
0371:                ListIterator iterator = list.listIterator(0);
0372:
0373:                while (iterator.hasNext()) {
0374:                    Entry entry = (Entry) iterator.next();
0375:
0376:                    if (entry.component == component)
0377:                        iterator.set(new Entry(component, constraint));
0378:                }
0379:            }
0380:
0381:            /**
0382:             * Adjusts the number and sizes of rows in this layout. After calling this
0383:             * method, the caller should request this layout manager to perform the
0384:             * layout. This can be done with the following code:
0385:             * 
0386:             * <pre>
0387:             * layout.layoutContainer(container);
0388:             * container.repaint();
0389:             * </pre>
0390:             * 
0391:             * or
0392:             * 
0393:             * <pre>
0394:             * window.pack()
0395:             * </pre>
0396:             * 
0397:             * If this is not done, the changes in the layout will not be seen until the
0398:             * container is resized.
0399:             * 
0400:             * @param column
0401:             *            heights of each of the columns
0402:             * 
0403:             * @see getColumn
0404:             */
0405:
0406:            public void setColumn(double column[]) {
0407:                // Copy columns
0408:                columnSpec = new double[column.length];
0409:                System.arraycopy(column, 0, columnSpec, 0, columnSpec.length);
0410:
0411:                // Make sure columns are valid
0412:                for (int counter = 0; counter < columnSpec.length; counter++)
0413:                    if ((columnSpec[counter] < 0.0)
0414:                            && (columnSpec[counter] != FILL)
0415:                            && (columnSpec[counter] != PREFERRED)
0416:                            && (columnSpec[counter] != MINIMUM)) {
0417:                        columnSpec[counter] = 0.0;
0418:                    }
0419:
0420:                // Indicate that the cell sizes are not known
0421:                dirty = true;
0422:            }
0423:
0424:            /**
0425:             * Adjusts the number and sizes of rows in this layout. After calling this
0426:             * method, the caller should request this layout manager to perform the
0427:             * layout. This can be done with the following code:
0428:             * 
0429:             * <code>
0430:             *     layout.layoutContainer(container);
0431:             *     container.repaint();
0432:             * </code>
0433:             * 
0434:             * or
0435:             * 
0436:             * <pre>
0437:             * window.pack()
0438:             * </pre>
0439:             * 
0440:             * If this is not done, the changes in the layout will not be seen until the
0441:             * container is resized.
0442:             * 
0443:             * @param row
0444:             *            widths of each of the rows. This parameter cannot be null.
0445:             * 
0446:             * @see getRow
0447:             */
0448:
0449:            public void setRow(double row[]) {
0450:                // Copy rows
0451:                rowSpec = new double[row.length];
0452:                System.arraycopy(row, 0, rowSpec, 0, rowSpec.length);
0453:
0454:                // Make sure rows are valid
0455:                for (int counter = 0; counter < rowSpec.length; counter++)
0456:                    if ((rowSpec[counter] < 0.0) && (rowSpec[counter] != FILL)
0457:                            && (rowSpec[counter] != PREFERRED)
0458:                            && (rowSpec[counter] != MINIMUM)) {
0459:                        rowSpec[counter] = 0.0;
0460:                    }
0461:
0462:                // Indicate that the cell sizes are not known
0463:                dirty = true;
0464:            }
0465:
0466:            /**
0467:             * Adjusts the width of a single column in this layout. After calling this
0468:             * method, the caller should request this layout manager to perform the
0469:             * layout. This can be done with the following code:
0470:             * 
0471:             * <code>
0472:             *     layout.layoutContainer(container);
0473:             *     container.repaint();
0474:             * </code>
0475:             * 
0476:             * or
0477:             * 
0478:             * <pre>
0479:             * window.pack()
0480:             * </pre>
0481:             * 
0482:             * If this is not done, the changes in the layout will not be seen until the
0483:             * container is resized.
0484:             * 
0485:             * @param i
0486:             *            zero-based index of column to set. If this parameter is not
0487:             *            valid, an ArrayOutOfBoundsException will be thrown.
0488:             * @param size
0489:             *            width of the column. This parameter cannot be null.
0490:             * 
0491:             * @see getColumn
0492:             */
0493:
0494:            public void setColumn(int i, double size) {
0495:                // Make sure size is valid
0496:                if ((size < 0.0) && (size != FILL) && (size != PREFERRED)
0497:                        && (size != MINIMUM)) {
0498:                    size = 0.0;
0499:                }
0500:
0501:                // Copy new size
0502:                columnSpec[i] = size;
0503:
0504:                // Indicate that the cell sizes are not known
0505:                dirty = true;
0506:            }
0507:
0508:            /**
0509:             * Adjusts the height of a single row in this layout. After calling this
0510:             * method, the caller should request this layout manager to perform the
0511:             * layout. This can be done with the following code:
0512:             * 
0513:             * <code>
0514:             *     layout.layoutContainer(container);
0515:             *     container.repaint();
0516:             * </code>
0517:             * 
0518:             * or
0519:             * 
0520:             * <pre>
0521:             * window.pack()
0522:             * </pre>
0523:             * 
0524:             * If this is not done, the changes in the layout will not be seen until the
0525:             * container is resized.
0526:             * 
0527:             * @param i
0528:             *            zero-based index of row to set. If this parameter is not
0529:             *            valid, an ArrayOutOfBoundsException will be thrown.
0530:             * @param size
0531:             *            height of the row. This parameter cannot be null.
0532:             * 
0533:             * @see getRow
0534:             */
0535:
0536:            public void setRow(int i, double size) {
0537:                // Make sure size is valid
0538:                if ((size < 0.0) && (size != FILL) && (size != PREFERRED)
0539:                        && (size != MINIMUM)) {
0540:                    size = 0.0;
0541:                }
0542:
0543:                // Copy new size
0544:                rowSpec[i] = size;
0545:
0546:                // Indicate that the cell sizes are not known
0547:                dirty = true;
0548:            }
0549:
0550:            /**
0551:             * Gets the sizes of columns in this layout.
0552:             * 
0553:             * @return widths of each of the columns
0554:             * 
0555:             * @see setColumn
0556:             */
0557:
0558:            public double[] getColumn() {
0559:                // Copy columns
0560:                double column[] = new double[columnSpec.length];
0561:                System.arraycopy(columnSpec, 0, column, 0, column.length);
0562:
0563:                return column;
0564:            }
0565:
0566:            /**
0567:             * Gets the height of a single row in this layout.
0568:             * 
0569:             * @return height of the requested row
0570:             * 
0571:             * @see setRow
0572:             */
0573:
0574:            public double[] getRow() {
0575:                // Copy rows
0576:                double row[] = new double[rowSpec.length];
0577:                System.arraycopy(rowSpec, 0, row, 0, row.length);
0578:
0579:                return row;
0580:            }
0581:
0582:            /**
0583:             * Gets the width of a single column in this layout.
0584:             * 
0585:             * @param i
0586:             *            zero-based index of row to get. If this parameter is not
0587:             *            valid, an ArrayOutOfBoundsException will be thrown.
0588:             * 
0589:             * @return width of the requested column
0590:             * 
0591:             * @see setRow
0592:             */
0593:
0594:            public double getColumn(int i) {
0595:                return columnSpec[i];
0596:            }
0597:
0598:            /**
0599:             * Gets the sizes of a row in this layout.
0600:             * 
0601:             * @param i
0602:             *            zero-based index of row to get. If this parameter is not
0603:             *            valid, an ArrayOutOfBoundsException will be thrown.
0604:             * 
0605:             * @return height of each of the requested row
0606:             * 
0607:             * @see setRow
0608:             */
0609:
0610:            public double getRow(int i) {
0611:                return rowSpec[i];
0612:            }
0613:
0614:            /**
0615:             * Gets the number of columns in this layout.
0616:             * 
0617:             * @return the number of columns
0618:             */
0619:
0620:            public int getNumColumn() {
0621:                return columnSpec.length;
0622:            }
0623:
0624:            /**
0625:             * Gets the number of rows in this layout.
0626:             * 
0627:             * @return the number of rows
0628:             */
0629:
0630:            public int getNumRow() {
0631:                return rowSpec.length;
0632:            }
0633:
0634:            // ******************************************************************************
0635:            // ** Insertion/Deletion methods ***
0636:            // ******************************************************************************
0637:
0638:            /**
0639:             * Inserts a column in this layout. All components to the right of the
0640:             * insertion point are moved right one column. The container will need to be
0641:             * laid out after this method returns. See <code>setColumn</code>.
0642:             * 
0643:             * @param i
0644:             *            zero-based index at which to insert the column.
0645:             * @param size
0646:             *            size of the column to be inserted
0647:             * 
0648:             * @see setColumn
0649:             * @see deleteColumn
0650:             */
0651:
0652:            public void insertColumn(int i, double size) {
0653:                // Make sure position is valid
0654:                if ((i < 0) || (i > columnSpec.length))
0655:                    throw new IllegalArgumentException(
0656:                            "Parameter i is invalid.  i = " + i
0657:                                    + ".  Valid range is [0, "
0658:                                    + columnSpec.length + "].");
0659:
0660:                // Make sure column size is valid
0661:                if ((size < 0.0) && (size != FILL) && (size != PREFERRED)
0662:                        && (size != MINIMUM)) {
0663:                    size = 0.0;
0664:                }
0665:
0666:                // Copy columns
0667:                double column[] = new double[columnSpec.length + 1];
0668:                System.arraycopy(columnSpec, 0, column, 0, i);
0669:                System.arraycopy(columnSpec, i, column, i + 1,
0670:                        columnSpec.length - i);
0671:
0672:                // Insert column
0673:                column[i] = size;
0674:                columnSpec = column;
0675:
0676:                // Move all components that are to the right of new row
0677:                ListIterator iterator = list.listIterator(0);
0678:
0679:                while (iterator.hasNext()) {
0680:                    // Get next entry
0681:                    Entry entry = (Entry) iterator.next();
0682:
0683:                    // Is the first column to the right of the new column
0684:                    if (entry.col1 >= i)
0685:                        // Move first column
0686:                        entry.col1++;
0687:
0688:                    // Is the second column to the right of the new column
0689:                    if (entry.col2 >= i)
0690:                        // Move second column
0691:                        entry.col2++;
0692:                }
0693:
0694:                // Indicate that the cell sizes are not known
0695:                dirty = true;
0696:            }
0697:
0698:            /**
0699:             * Inserts a row in this layout. All components below the insertion point
0700:             * are moved down one row. The container will need to be laid out after this
0701:             * method returns. See <code>setRow</code>.
0702:             * 
0703:             * @param i
0704:             *            zero-based index at which to insert the column.
0705:             * @param size
0706:             *            size of the row to be inserted
0707:             * 
0708:             * @see setRow
0709:             * @see deleteRow
0710:             */
0711:
0712:            public void insertRow(int i, double size) {
0713:                // Make sure position is valid
0714:                if ((i < 0) || (i > rowSpec.length))
0715:                    throw new IllegalArgumentException(
0716:                            "Parameter i is invalid.  i = " + i
0717:                                    + ".  Valid range is [0, " + rowSpec.length
0718:                                    + "].");
0719:
0720:                // Make sure row size is valid
0721:                if ((size < 0.0) && (size != FILL) && (size != PREFERRED)
0722:                        && (size != MINIMUM)) {
0723:                    size = 0.0;
0724:                }
0725:
0726:                // Copy rows
0727:                double row[] = new double[rowSpec.length + 1];
0728:                System.arraycopy(rowSpec, 0, row, 0, i);
0729:                System.arraycopy(rowSpec, i, row, i + 1, rowSpec.length - i);
0730:
0731:                // Insert row
0732:                row[i] = size;
0733:                rowSpec = row;
0734:
0735:                // Move all components that are below the new row
0736:                ListIterator iterator = list.listIterator(0);
0737:
0738:                while (iterator.hasNext()) {
0739:                    // Get next entry
0740:                    Entry entry = (Entry) iterator.next();
0741:
0742:                    // Is the first row to the right of the new row
0743:                    if (entry.row1 >= i)
0744:                        // Move first row
0745:                        entry.row1++;
0746:
0747:                    // Is the second row to the right of the new row
0748:                    if (entry.row2 >= i)
0749:                        // Move second row
0750:                        entry.row2++;
0751:                }
0752:
0753:                // Indicate that the cell sizes are not known
0754:                dirty = true;
0755:            }
0756:
0757:            /**
0758:             * Deletes a column in this layout. All components to the right of the
0759:             * deletion point are moved left one column. The container will need to be
0760:             * laid out after this method returns. See <code>setColumn</code>.
0761:             * 
0762:             * @param i
0763:             *            zero-based index of column to delete
0764:             * 
0765:             * @see setColumn
0766:             * @see deleteColumn
0767:             */
0768:
0769:            public void deleteColumn(int i) {
0770:                // Make sure position is valid
0771:                if ((i < 0) || (i >= columnSpec.length))
0772:                    throw new IllegalArgumentException(
0773:                            "Parameter i is invalid.  i = " + i
0774:                                    + ".  Valid range is [0, "
0775:                                    + (columnSpec.length - 1) + "].");
0776:
0777:                // Copy columns
0778:                double column[] = new double[columnSpec.length - 1];
0779:                System.arraycopy(columnSpec, 0, column, 0, i);
0780:                System.arraycopy(columnSpec, i + 1, column, i,
0781:                        columnSpec.length - i - 1);
0782:
0783:                // Delete column
0784:                columnSpec = column;
0785:
0786:                // Move all components that are to the right of row deleted
0787:                ListIterator iterator = list.listIterator(0);
0788:
0789:                while (iterator.hasNext()) {
0790:                    // Get next entry
0791:                    Entry entry = (Entry) iterator.next();
0792:
0793:                    // Is the first column to the right of the new column
0794:                    if (entry.col1 >= i)
0795:                        // Move first column
0796:                        entry.col1--;
0797:
0798:                    // Is the second column to the right of the new column
0799:                    if (entry.col2 >= i)
0800:                        // Move second column
0801:                        entry.col2--;
0802:                }
0803:
0804:                // Indicate that the cell sizes are not known
0805:                dirty = true;
0806:            }
0807:
0808:            /**
0809:             * Deletes a row in this layout. All components below the deletion point are
0810:             * moved up one row. The container will need to be laid out after this
0811:             * method returns. See <code>setRow</code>. There must be at least two
0812:             * rows in order to delete a row.
0813:             * 
0814:             * @param i
0815:             *            zero-based index of column to delete
0816:             * 
0817:             * @see setRow
0818:             * @see deleteRow
0819:             */
0820:
0821:            public void deleteRow(int i) {
0822:                // Make sure position is valid
0823:                if ((i < 0) || (i >= rowSpec.length))
0824:                    throw new IllegalArgumentException(
0825:                            "Parameter i is invalid.  i = " + i
0826:                                    + ".  Valid range is [0, "
0827:                                    + (rowSpec.length - 1) + "].");
0828:
0829:                // Copy rows
0830:                double row[] = new double[rowSpec.length - 1];
0831:                System.arraycopy(rowSpec, 0, row, 0, i);
0832:                System
0833:                        .arraycopy(rowSpec, i + 1, row, i, rowSpec.length - i
0834:                                - 1);
0835:
0836:                // Delete row
0837:                rowSpec = row;
0838:
0839:                // Move all components that are to below the row deleted
0840:                ListIterator iterator = list.listIterator(0);
0841:
0842:                while (iterator.hasNext()) {
0843:                    // Get next entry
0844:                    Entry entry = (Entry) iterator.next();
0845:
0846:                    // Is the first row below the new row
0847:                    if (entry.row1 >= i)
0848:                        // Move first row
0849:                        entry.row1--;
0850:
0851:                    // Is the second row below the new row
0852:                    if (entry.row2 >= i)
0853:                        // Move second row
0854:                        entry.row2--;
0855:                }
0856:
0857:                // Indicate that the cell sizes are not known
0858:                dirty = true;
0859:            }
0860:
0861:            // ******************************************************************************
0862:            // ** Misc methods ***
0863:            // ******************************************************************************
0864:
0865:            /**
0866:             * Converts this TableLayout to a string.
0867:             * 
0868:             * @return a string representing the columns and row sizes in the form
0869:             *         "{{col0, col1, col2, ..., colN}, {row0, row1, row2, ..., rowM}}"
0870:             */
0871:
0872:            public String toString() {
0873:                int counter;
0874:
0875:                String value = "TableLayout {{";
0876:
0877:                if (columnSpec.length > 0) {
0878:                    for (counter = 0; counter < columnSpec.length - 1; counter++)
0879:                        value += columnSpec[counter] + ", ";
0880:
0881:                    value += columnSpec[columnSpec.length - 1] + "}, {";
0882:                } else
0883:                    value += "}, {";
0884:
0885:                if (rowSpec.length > 0) {
0886:                    for (counter = 0; counter < rowSpec.length - 1; counter++)
0887:                        value += rowSpec[counter] + ", ";
0888:
0889:                    value += rowSpec[rowSpec.length - 1] + "}}";
0890:                } else
0891:                    value += "}}";
0892:
0893:                return value;
0894:            }
0895:
0896:            /**
0897:             * Draws a grid on the given container. This is useful for seeing where the
0898:             * rows and columns go. In the container's paint method, call this method.
0899:             * 
0900:             * @param container
0901:             *            container using this TableLayout
0902:             * @param g
0903:             *            graphics content of container (can be offscreen)
0904:             */
0905:
0906:            public void drawGrid(Container container, Graphics g) {
0907:                int counter; // Counting variable;
0908:
0909:                // Calculate the sizes of the rows and columns
0910:                Dimension d = container.getSize();
0911:
0912:                if (dirty || (d.width != oldWidth) || (d.height != oldHeight))
0913:                    calculateSize(container);
0914:
0915:                // Initialize y
0916:                int y = 0;
0917:
0918:                for (int row = 0; row < rowSize.length; row++) {
0919:                    // Initialize x
0920:                    int x = 0;
0921:
0922:                    for (int column = 0; column < columnSize.length; column++) {
0923:                        // Use a random color to make things easy to see
0924:                        Color color = new Color(
0925:                                (int) (Math.random() * 0xFFFFFFL));
0926:                        g.setColor(color);
0927:
0928:                        // Draw the cell as a solid rectangle
0929:                        g.fillRect(x, y, columnSize[column], rowSize[row]);
0930:
0931:                        // Increment x
0932:                        x += columnSize[column];
0933:                    }
0934:
0935:                    // Increment y
0936:                    y += rowSize[row];
0937:                }
0938:            }
0939:
0940:            /**
0941:             * Determines whether or not there are any hidden components. A hidden
0942:             * component is one that will not be shown with this layout's current
0943:             * configuration. Such a component is, at least partly, in an invalid row or
0944:             * column. For example, on a table with five rows, row -1 and row 5 are both
0945:             * invalid. Valid rows are 0 through 4, inclusively.
0946:             * 
0947:             * @return True, if there are any hidden components. False, otherwise.
0948:             * 
0949:             * @see overlapping
0950:             */
0951:
0952:            public boolean hidden() {
0953:                // Assume no components are hidden
0954:                boolean hidden = false;
0955:
0956:                // Check all components
0957:                ListIterator iterator = list.listIterator(0);
0958:
0959:                while (iterator.hasNext()) {
0960:                    // Get next entry
0961:                    Entry entry = (Entry) iterator.next();
0962:
0963:                    // Is this component valid
0964:                    if ((entry.row1 < 0) || (entry.col1 < 0)
0965:                            || (entry.row2 > rowSpec.length)
0966:                            || (entry.col2 > columnSpec.length)) {
0967:                        hidden = true;
0968:                        break;
0969:                    }
0970:                }
0971:
0972:                return hidden;
0973:            }
0974:
0975:            /**
0976:             * Determines whether or not there are any overlapping components. Two
0977:             * components overlap if they cover at least one common cell.
0978:             * 
0979:             * @return True, if there are any overlapping components. False, otherwise.
0980:             * 
0981:             * @see hidden
0982:             */
0983:
0984:            public boolean overlapping() {
0985:                // Count constraints
0986:                int numEntry = list.size();
0987:
0988:                // If there are no components, they can't be overlapping
0989:                if (numEntry == 0)
0990:                    return false;
0991:
0992:                // Assume no components are overlapping
0993:                boolean overlapping = false;
0994:
0995:                // Put entries in an array
0996:                Entry entry[] = (Entry[]) list.toArray(new Entry[numEntry]);
0997:
0998:                // Check all components
0999:                for (int knowUnique = 1; knowUnique < numEntry; knowUnique++)
1000:                    for (int checking = knowUnique - 1; checking >= 0; checking--)
1001:                        if (((entry[checking].col1 >= entry[knowUnique].col1)
1002:                                && (entry[checking].col1 <= entry[knowUnique].col2)
1003:                                && (entry[checking].row1 >= entry[knowUnique].row1) && (entry[checking].row1 <= entry[knowUnique].row2))
1004:                                || ((entry[checking].col2 >= entry[knowUnique].col1)
1005:                                        && (entry[checking].col2 <= entry[knowUnique].col2)
1006:                                        && (entry[checking].row2 >= entry[knowUnique].row1) && (entry[checking].row2 <= entry[knowUnique].row2))) {
1007:                            overlapping = true;
1008:                            break;
1009:                        }
1010:
1011:                return overlapping;
1012:            }
1013:
1014:            /**
1015:             * Calculates the sizes of the rows and columns based on the absolute and
1016:             * relative sizes specified in <code>rowSpec</code> and
1017:             * <code>columnSpec</code> and the size of the container. The result is
1018:             * stored in <code>rowSize</code> and <code>columnSize</code>.
1019:             * 
1020:             * @param container
1021:             *            container using this TableLayout
1022:             */
1023:
1024:            protected void calculateSize(Container container) {
1025:                int counter; // Counting variable;
1026:
1027:                // Get number of rows and columns
1028:                int numColumn = columnSpec.length;
1029:                int numRow = rowSpec.length;
1030:
1031:                // Create array to hold actual sizes in pixels
1032:                columnSize = new int[numColumn];
1033:                rowSize = new int[numRow];
1034:
1035:                // Get the container's insets
1036:                Insets inset = container.getInsets();
1037:
1038:                // Get the size of the container's available space
1039:                Dimension d = container.getSize();
1040:                int totalWidth = d.width - inset.left - inset.right;
1041:                int totalHeight = d.height - inset.top - inset.bottom;
1042:
1043:                // Initially, the available space is the total space
1044:                int availableWidth = totalWidth;
1045:                int availableHeight = totalHeight;
1046:
1047:                // Assign absolute widths; this reduces available width
1048:                for (counter = 0; counter < numColumn; counter++)
1049:                    // Is the current column an absolue size
1050:                    if ((columnSpec[counter] >= 1.0)
1051:                            || (columnSpec[counter] == 0.0)) {
1052:                        // Assign absolute width
1053:                        columnSize[counter] = (int) (columnSpec[counter] + 0.5);
1054:
1055:                        // Reduce available width
1056:                        availableWidth -= columnSize[counter];
1057:                    }
1058:
1059:                // Assign absolute heights; this reduces available height
1060:                for (counter = 0; counter < numRow; counter++)
1061:                    // Is the current column an absolue size
1062:                    if ((rowSpec[counter] >= 1.0) || (rowSpec[counter] == 0.0)) {
1063:                        // Assign absolute width
1064:                        rowSize[counter] = (int) (rowSpec[counter] + 0.5);
1065:
1066:                        // Reduce available width
1067:                        availableHeight -= rowSize[counter];
1068:                    }
1069:
1070:                // Assign preferred and minimum widths; this reduces available width.
1071:                // Assignment of preferred/minimum with is like assignment of absolute
1072:                // widths except that each column must determine the maximum
1073:                // preferred/minimum width of the components that are completely
1074:                // contained
1075:                // within the column.
1076:                for (counter = 0; counter < numColumn; counter++)
1077:                    // Is the current column a preferred size
1078:                    if ((columnSpec[counter] == PREFERRED)
1079:                            || (columnSpec[counter] == MINIMUM)) {
1080:                        // Assume a maximum width of zero
1081:                        int maxWidth = 0;
1082:
1083:                        // Find maximum preferred width of all components completely
1084:                        // contained within this column
1085:                        ListIterator iterator = list.listIterator(0);
1086:
1087:                        while (iterator.hasNext()) {
1088:                            Entry entry = (Entry) iterator.next();
1089:
1090:                            if ((entry.col1 == counter)
1091:                                    && (entry.col2 == counter)) {
1092:                                Dimension p = (columnSpec[counter] == PREFERRED) ? entry.component
1093:                                        .getPreferredSize()
1094:                                        : entry.component.getMinimumSize();
1095:
1096:                                int width = (p == null) ? 0 : p.width;
1097:
1098:                                if (maxWidth < width)
1099:                                    maxWidth = width;
1100:                            }
1101:                        }
1102:
1103:                        // Assign preferred width
1104:                        columnSize[counter] = maxWidth;
1105:
1106:                        // Reduce available width
1107:                        availableWidth -= maxWidth;
1108:                    }
1109:
1110:                // Assign preferred and minimum heights; this reduces available height.
1111:                // Assignment of preferred/minimum with is like assignment of absolute
1112:                // heights except that each row must determine the maximum
1113:                // preferred/minimum height of the components that are completely
1114:                // contained
1115:                // within the row.
1116:                for (counter = 0; counter < numRow; counter++)
1117:                    // Is the current row a preferred size
1118:                    if ((rowSpec[counter] == PREFERRED)
1119:                            || (rowSpec[counter] == MINIMUM)) {
1120:                        // Assume a maximum height of zero
1121:                        int maxHeight = 0;
1122:
1123:                        // Find maximum preferred height of all components completely
1124:                        // contained within this row
1125:                        ListIterator iterator = list.listIterator(0);
1126:
1127:                        while (iterator.hasNext()) {
1128:                            Entry entry = (Entry) iterator.next();
1129:
1130:                            if ((entry.row1 == counter)
1131:                                    && (entry.row2 == counter)) {
1132:                                Dimension p = (rowSpec[counter] == PREFERRED) ? entry.component
1133:                                        .getPreferredSize()
1134:                                        : entry.component.getMinimumSize();
1135:
1136:                                int height = (p == null) ? 0 : p.height;
1137:
1138:                                if (maxHeight < height)
1139:                                    maxHeight = height;
1140:                            }
1141:                        }
1142:
1143:                        // Assign preferred height
1144:                        rowSize[counter] = maxHeight;
1145:
1146:                        // Reduce available height
1147:                        availableHeight -= maxHeight;
1148:                    }
1149:
1150:                // Remember how much space is available for relatively sized cells
1151:                int relativeWidth = availableWidth;
1152:                int relativeHeight = availableHeight;
1153:
1154:                // Make sure relativeWidth and relativeHeight are non-negative
1155:                if (relativeWidth < 0)
1156:                    relativeWidth = 0;
1157:
1158:                if (relativeHeight < 0)
1159:                    relativeHeight = 0;
1160:
1161:                // Assign relative widths
1162:                for (counter = 0; counter < numColumn; counter++)
1163:                    // Is the current column an relative size
1164:                    if ((columnSpec[counter] > 0.0)
1165:                            && (columnSpec[counter] < 1.0)) {
1166:                        // Assign relative width
1167:                        columnSize[counter] = (int) (columnSpec[counter]
1168:                                * relativeWidth + 0.5);
1169:
1170:                        // Reduce available width
1171:                        availableWidth -= columnSize[counter];
1172:                    }
1173:
1174:                // Assign relative widths
1175:                for (counter = 0; counter < numRow; counter++)
1176:                    // Is the current column an relative size
1177:                    if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0)) {
1178:                        // Assign relative width
1179:                        rowSize[counter] = (int) (rowSpec[counter]
1180:                                * relativeHeight + 0.5);
1181:
1182:                        // Reduce available width
1183:                        availableHeight -= rowSize[counter];
1184:                    }
1185:
1186:                // Make sure availableWidth and availableHeight are non-negative
1187:                if (availableWidth < 0)
1188:                    availableWidth = 0;
1189:
1190:                if (availableHeight < 0)
1191:                    availableHeight = 0;
1192:
1193:                // Count the number of "fill" cells
1194:                int numFillWidth = 0;
1195:                int numFillHeight = 0;
1196:
1197:                for (counter = 0; counter < numColumn; counter++)
1198:                    if (columnSpec[counter] == FILL)
1199:                        numFillWidth++;
1200:
1201:                for (counter = 0; counter < numRow; counter++)
1202:                    if (rowSpec[counter] == FILL)
1203:                        numFillHeight++;
1204:
1205:                // If numFillWidth (numFillHeight) is zero, the cooresponding if
1206:                // statements
1207:                // will always evaluate to false and the division will not occur.
1208:
1209:                // If there are more than one "fill" cell, slack may occur due to
1210:                // rounding
1211:                // errors
1212:                int slackWidth = availableWidth;
1213:                int slackHeight = availableHeight;
1214:
1215:                // Assign "fill" cells equal amounts of the remaining space
1216:                for (counter = 0; counter < numColumn; counter++)
1217:                    if (columnSpec[counter] == FILL) {
1218:                        columnSize[counter] = availableWidth / numFillWidth;
1219:                        slackWidth -= columnSize[counter];
1220:                    }
1221:
1222:                for (counter = 0; counter < numRow; counter++)
1223:                    if (rowSpec[counter] == FILL) {
1224:                        rowSize[counter] = availableHeight / numFillHeight;
1225:                        slackHeight -= rowSize[counter];
1226:                    }
1227:
1228:                // Add slack to the last "fill" cell
1229:                for (counter = numColumn - 1; counter >= 0; counter--) {
1230:                    if (columnSpec[counter] == FILL) {
1231:                        columnSize[counter] += slackWidth;
1232:                        break;
1233:                    }
1234:                }
1235:
1236:                for (counter = numRow - 1; counter >= 0; counter--) {
1237:                    if (rowSpec[counter] == FILL) {
1238:                        rowSize[counter] += slackHeight;
1239:                        break;
1240:                    }
1241:                }
1242:
1243:                // Calculate offsets of each column (done for effeciency)
1244:                columnOffset = new int[numColumn + 1];
1245:                columnOffset[0] = inset.left;
1246:
1247:                for (counter = 0; counter < numColumn; counter++)
1248:                    columnOffset[counter + 1] = columnOffset[counter]
1249:                            + columnSize[counter];
1250:
1251:                // Calculate offsets of each row (done for effeciency)
1252:                rowOffset = new int[numRow + 1];
1253:                rowOffset[0] = inset.top;
1254:
1255:                for (counter = 0; counter < numRow; counter++)
1256:                    rowOffset[counter + 1] = rowOffset[counter]
1257:                            + rowSize[counter];
1258:
1259:                // Indicate that the size of the cells are known for the container's
1260:                // current size
1261:                dirty = false;
1262:                oldWidth = totalWidth;
1263:                oldHeight = totalHeight;
1264:            }
1265:
1266:            // ******************************************************************************
1267:            // ** java.awt.event.LayoutManager methods ***
1268:            // ******************************************************************************
1269:
1270:            /**
1271:             * To lay out the specified container using this layout. This method
1272:             * reshapes the components in the specified target container in order to
1273:             * satisfy the constraints of all components.
1274:             * 
1275:             * <p>
1276:             * User code should not have to call this method directly.
1277:             * </p>
1278:             * 
1279:             * @param container
1280:             *            container being served by this layout manager
1281:             */
1282:
1283:            public void layoutContainer(Container container) {
1284:                int x, y; // Coordinates of the currnet component in pixels
1285:                int w, h; // Width and height of the current component in pixels
1286:
1287:                // Calculate sizes if container has changed size or components were
1288:                // added
1289:                Dimension d = container.getSize();
1290:
1291:                if (dirty || (d.width != oldWidth) || (d.height != oldHeight))
1292:                    calculateSize(container);
1293:
1294:                // Get components
1295:                Component component[] = container.getComponents();
1296:
1297:                // Layout components
1298:                for (int counter = 0; counter < component.length; counter++) {
1299:                    try {
1300:                        // Get the entry entry for the next component
1301:                        ListIterator iterator = list.listIterator(0);
1302:                        Entry entry = null;
1303:
1304:                        while (iterator.hasNext()) {
1305:                            entry = (Entry) iterator.next();
1306:
1307:                            if (entry.component == component[counter])
1308:                                break;
1309:                            else
1310:                                entry = null;
1311:                        }
1312:
1313:                        // Skip any components that have not been place in a specific
1314:                        // cell
1315:                        if (entry == null)
1316:                            break;
1317:
1318:                        // Olli Z. dropped general different handling of composed and
1319:                        // atomic cell
1320:                        // applied check for single cell where needed in individual case
1321:                        // now alignment works for composed cells
1322:
1323:                        // The following block of code has been optimized so that the
1324:                        // preferred size of the component is only obtained if it is
1325:                        // needed. There are components in which the getPreferredSize
1326:                        // method is extremely expensive, such as data driven controls
1327:                        // with a large amount of data.
1328:
1329:                        // Get the preferred size of the component
1330:                        int preferredWidth = 0;
1331:                        int preferredHeight = 0;
1332:
1333:                        if ((entry.hAlign != FULL) || (entry.vAlign != FULL)) {
1334:                            Dimension preferredSize = component[counter]
1335:                                    .getPreferredSize();
1336:
1337:                            preferredWidth = preferredSize.width;
1338:                            preferredHeight = preferredSize.height;
1339:                        }
1340:
1341:                        // Determine cell width and height
1342:
1343:                        int cellWidth = (entry.singleCell ? columnSize[entry.col1]
1344:                                : columnOffset[entry.col2 + 1]
1345:                                        - columnOffset[entry.col1]);
1346:                        int cellHeight = (entry.singleCell ? rowSize[entry.row1]
1347:                                : rowOffset[entry.row2 + 1]
1348:                                        - rowOffset[entry.row1]);
1349:
1350:                        // Determine the width of the component
1351:                        if ((entry.hAlign == FULL)
1352:                                || (cellWidth < preferredWidth)) {
1353:                            // Use the width of the cell
1354:                            w = cellWidth;
1355:                        } else {
1356:                            // Use the prefered width of the component
1357:                            w = preferredWidth;
1358:                        }
1359:
1360:                        // Determine left and right boarders
1361:                        switch (entry.hAlign) {
1362:                        case LEFT:
1363:                            // Align left side along left edge of cell
1364:                            x = columnOffset[entry.col1];
1365:                            break;
1366:
1367:                        case RIGHT:
1368:                            // Align right side along right edge of cell
1369:                            x = (entry.singleCell ? columnOffset[entry.col1 + 1]
1370:                                    - w
1371:                                    : columnOffset[entry.col2 + 1] - w);
1372:                            break;
1373:
1374:                        case CENTER:
1375:                            // Center justify component
1376:                            x = columnOffset[entry.col1]
1377:                                    + ((cellWidth - w) >> 1);
1378:                            break;
1379:
1380:                        case FULL:
1381:                            // Align left side along left edge of cell
1382:                            x = columnOffset[entry.col1];
1383:                            break;
1384:
1385:                        default:
1386:                            // This is a never should happen case, but just in case
1387:                            x = 0;
1388:                        }
1389:
1390:                        // Determine the height of the component
1391:                        if ((entry.vAlign == FULL)
1392:                                || (cellHeight < preferredHeight))
1393:                            // Use the height of the cell
1394:                            h = cellHeight;
1395:                        else
1396:                            // Use the prefered height of the component
1397:                            h = preferredHeight;
1398:
1399:                        // Determine top and bottom boarders
1400:                        switch (entry.vAlign) {
1401:                        case TOP:
1402:                            // Align top side along top edge of cell
1403:                            y = rowOffset[entry.row1];
1404:                            break;
1405:
1406:                        case BOTTOM:
1407:                            // Align right side along right edge of cell
1408:                            y = (entry.singleCell ? rowOffset[entry.row1 + 1]
1409:                                    - h : rowOffset[entry.row2 + 1] - h);
1410:                            break;
1411:
1412:                        case CENTER:
1413:                            // Center justify component
1414:                            y = rowOffset[entry.row1] + ((cellHeight - h) >> 1);
1415:                            break;
1416:
1417:                        case FULL:
1418:                            // Align right side along right edge of cell
1419:                            y = rowOffset[entry.row1];
1420:                            break;
1421:
1422:                        default:
1423:                            // This is a never should happen case, but just in case
1424:                            y = 0;
1425:                        }
1426:                        // Move and resize component
1427:                        component[counter].setBounds(x, y, w, h);
1428:                    } catch (Exception error) {
1429:                        // If any error occurs, skip this component
1430:                        continue;
1431:                    }
1432:                }
1433:            }
1434:
1435:            /**
1436:             * Determines the preferred size of the container argument using this
1437:             * layout. The preferred size is the smallest size that, if used for the
1438:             * container's size, will ensure that all components are at least as large
1439:             * as their preferred size. This method cannot guarantee that all components
1440:             * will be their preferred size. For example, if component A and component B
1441:             * are each allocate half of the container's width and component A wants to
1442:             * be 10 pixels wide while component B wants to be 100 pixels wide, they
1443:             * cannot both be accommodated. Since in general components rather be larger
1444:             * than their preferred size instead of smaller, component B's request will
1445:             * be fulfilled. The preferred size of the container would be 200 pixels.
1446:             * 
1447:             * @param container
1448:             *            container being served by this layout manager
1449:             * 
1450:             * @return a dimension indicating the container's preferred size
1451:             */
1452:
1453:            public Dimension preferredLayoutSize(Container container) {
1454:                Dimension size; // Preferred size of current component
1455:                int scaledWidth = 0; // Preferred width of scalled components
1456:                int scaledHeight = 0; // Preferred height of scalled components
1457:                int temp; // Temporary variable used to compare sizes
1458:                int counter; // Counting variable
1459:
1460:                // Determine percentage of space allocated to fill components. This is
1461:                // one minus the sum of all scalable components.
1462:                double fillWidthRatio = 1.0;
1463:                double fillHeightRatio = 1.0;
1464:                int numFillWidth = 0;
1465:                int numFillHeight = 0;
1466:
1467:                for (counter = 0; counter < columnSpec.length; counter++)
1468:                    if ((columnSpec[counter] > 0.0)
1469:                            && (columnSpec[counter] < 1.0))
1470:                        fillWidthRatio -= columnSpec[counter];
1471:                    else if (columnSpec[counter] == FILL)
1472:                        numFillWidth++;
1473:
1474:                for (counter = 0; counter < rowSpec.length; counter++)
1475:                    if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0))
1476:                        fillHeightRatio -= rowSpec[counter];
1477:                    else if (rowSpec[counter] == FILL)
1478:                        numFillHeight++;
1479:
1480:                // Adjust fill ratios to reflect number of fill rows/columns
1481:                if (numFillWidth > 1)
1482:                    fillWidthRatio /= numFillWidth;
1483:
1484:                if (numFillHeight > 1)
1485:                    fillHeightRatio /= numFillHeight;
1486:
1487:                // Cap fill ratio bottoms to 0.0
1488:                if (fillWidthRatio < 0.0)
1489:                    fillWidthRatio = 0.0;
1490:
1491:                if (fillHeightRatio < 0.0)
1492:                    fillHeightRatio = 0.0;
1493:
1494:                // Calculate preferred/minimum column widths
1495:                int columnPrefMin[] = new int[columnSpec.length];
1496:
1497:                for (counter = 0; counter < columnSpec.length; counter++)
1498:                    // Is the current column a preferred/minimum size
1499:                    if ((columnSpec[counter] == PREFERRED)
1500:                            || (columnSpec[counter] == MINIMUM)) {
1501:                        // Assume a maximum width of zero
1502:                        int maxWidth = 0;
1503:
1504:                        // Find maximum preferred/minimum width of all components
1505:                        // completely
1506:                        // contained within this column
1507:                        ListIterator iterator = list.listIterator(0);
1508:
1509:                        while (iterator.hasNext()) {
1510:                            Entry entry = (Entry) iterator.next();
1511:
1512:                            if ((entry.col1 == counter)
1513:                                    && (entry.col2 == counter)) {
1514:                                Dimension p = (columnSpec[counter] == PREFERRED) ? entry.component
1515:                                        .getPreferredSize()
1516:                                        : entry.component.getMinimumSize();
1517:
1518:                                int width = (p == null) ? 0 : p.width;
1519:
1520:                                if (maxWidth < width)
1521:                                    maxWidth = width;
1522:                            }
1523:                        }
1524:
1525:                        // Set column's preferred/minimum width
1526:                        columnPrefMin[counter] = maxWidth;
1527:                    }
1528:
1529:                // Calculate preferred/minimum row heights
1530:                int rowPrefMin[] = new int[rowSpec.length];
1531:
1532:                for (counter = 0; counter < rowSpec.length; counter++)
1533:                    // Is the current row a preferred/minimum size
1534:                    if ((rowSpec[counter] == PREFERRED)
1535:                            || (rowSpec[counter] == MINIMUM)) {
1536:                        // Assume a maximum height of zero
1537:                        int maxHeight = 0;
1538:
1539:                        // Find maximum preferred height of all components completely
1540:                        // contained within this row
1541:                        ListIterator iterator = list.listIterator(0);
1542:
1543:                        while (iterator.hasNext()) {
1544:                            Entry entry = (Entry) iterator.next();
1545:
1546:                            if ((entry.row1 == counter)
1547:                                    && (entry.row1 == counter)) {
1548:                                Dimension p = (rowSpec[counter] == PREFERRED) ? entry.component
1549:                                        .getPreferredSize()
1550:                                        : entry.component.getMinimumSize();
1551:
1552:                                int height = (p == null) ? 0 : p.height;
1553:
1554:                                if (maxHeight < height)
1555:                                    maxHeight = height;
1556:                            }
1557:                        }
1558:
1559:                        // Add preferred height
1560:                        rowPrefMin[counter] += maxHeight;
1561:                    }
1562:
1563:                // Find maximum preferred size of all scaled components
1564:                ListIterator iterator = list.listIterator(0);
1565:
1566:                while (iterator.hasNext()) {
1567:                    // Get next entry
1568:                    Entry entry = (Entry) iterator.next();
1569:
1570:                    // Make sure entry is in valid rows and columns
1571:                    if ((entry.col1 < 0) || (entry.col1 >= columnSpec.length)
1572:                            || (entry.col2 >= columnSpec.length)
1573:                            || (entry.row1 < 0)
1574:                            || (entry.row1 >= rowSpec.length)
1575:                            || (entry.row2 >= rowSpec.length)) {
1576:                        // Skip the bad component
1577:                        continue;
1578:                    }
1579:
1580:                    // Get preferred size of current component
1581:                    size = entry.component.getPreferredSize();
1582:
1583:                    // Calculate portion of component that is not absolutely sized
1584:                    int scalableWidth = size.width;
1585:                    int scalableHeight = size.height;
1586:
1587:                    for (counter = entry.col1; counter <= entry.col2; counter++)
1588:                        if (columnSpec[counter] >= 1.0)
1589:                            scalableWidth -= columnSpec[counter];
1590:                        else if ((columnSpec[counter] == PREFERRED)
1591:                                || (columnSpec[counter] == MINIMUM)) {
1592:                            scalableWidth -= columnPrefMin[counter];
1593:                        }
1594:
1595:                    for (counter = entry.row1; counter <= entry.row2; counter++)
1596:                        if (rowSpec[counter] >= 1.0)
1597:                            scalableHeight -= rowSpec[counter];
1598:                        else if ((rowSpec[counter] == PREFERRED)
1599:                                || (rowSpec[counter] == MINIMUM)) {
1600:                            scalableHeight -= rowPrefMin[counter];
1601:                        }
1602:
1603:                    // ----------------------------------------------------------------------
1604:
1605:                    // Determine total percentage of scalable space that the component
1606:                    // occupies by adding the relative columns and the fill columns
1607:                    double relativeWidth = 0.0;
1608:
1609:                    for (counter = entry.col1; counter <= entry.col2; counter++) {
1610:                        // Column is scaled
1611:                        if ((columnSpec[counter] > 0.0)
1612:                                && (columnSpec[counter] < 1.0))
1613:                            // Add scaled size to relativeWidth
1614:                            relativeWidth += columnSpec[counter];
1615:                        // Column is fill
1616:                        else if ((columnSpec[counter] == FILL)
1617:                                && (fillWidthRatio != 0.0))
1618:                            // Add fill size to relativeWidth
1619:                            relativeWidth += fillWidthRatio;
1620:                    }
1621:
1622:                    // Determine the total scaled width as estimated by this component
1623:                    if (relativeWidth == 0)
1624:                        temp = 0;
1625:                    else
1626:                        temp = (int) (scalableWidth / relativeWidth + 0.5);
1627:
1628:                    // If the container needs to be bigger, make it so
1629:                    if (scaledWidth < temp)
1630:                        scaledWidth = temp;
1631:
1632:                    // ----------------------------------------------------------------------
1633:
1634:                    // Determine total percentage of scalable space that the component
1635:                    // occupies by adding the relative columns and the fill columns
1636:                    double relativeHeight = 0.0;
1637:
1638:                    for (counter = entry.row1; counter <= entry.row2; counter++) {
1639:                        // Row is scaled
1640:                        if ((rowSpec[counter] > 0.0)
1641:                                && (rowSpec[counter] < 1.0))
1642:                            // Add scaled size to relativeHeight
1643:                            relativeHeight += rowSpec[counter];
1644:                        // Row is fill
1645:                        else if ((rowSpec[counter] == FILL)
1646:                                && (fillHeightRatio != 0.0))
1647:                            // Add fill size to relativeHeight
1648:                            relativeHeight += fillHeightRatio;
1649:                    }
1650:
1651:                    // Determine the total scaled width as estimated by this component
1652:                    if (relativeHeight == 0)
1653:                        temp = 0;
1654:                    else
1655:                        temp = (int) (scalableHeight / relativeHeight + 0.5);
1656:
1657:                    // If the container needs to be bigger, make it so
1658:                    if (scaledHeight < temp)
1659:                        scaledHeight = temp;
1660:                }
1661:
1662:                // totalWidth is the scaledWidth plus the sum of all absolute widths and
1663:                // all
1664:                // preferred widths
1665:                int totalWidth = scaledWidth;
1666:
1667:                for (counter = 0; counter < columnSpec.length; counter++)
1668:                    // Is the current column an absolute size
1669:                    if (columnSpec[counter] >= 1.0)
1670:                        totalWidth += (int) (columnSpec[counter] + 0.5);
1671:                    // Is the current column a preferred/minimum size
1672:                    else if ((columnSpec[counter] == PREFERRED)
1673:                            || (columnSpec[counter] == MINIMUM)) {
1674:                        // Add preferred/minimum width
1675:                        totalWidth += columnPrefMin[counter];
1676:                    }
1677:
1678:                // totalHeight is the scaledHeight plus the sum of all absolute heights
1679:                // and
1680:                // all preferred widths
1681:                int totalHeight = scaledHeight;
1682:
1683:                for (counter = 0; counter < rowSpec.length; counter++)
1684:                    // Is the current row an absolute size
1685:                    if (rowSpec[counter] >= 1.0)
1686:                        totalHeight += (int) (rowSpec[counter] + 0.5);
1687:                    // Is the current row a preferred size
1688:                    else if ((rowSpec[counter] == PREFERRED)
1689:                            || (rowSpec[counter] == MINIMUM)) {
1690:                        // Add preferred/minimum width
1691:                        totalHeight += rowPrefMin[counter];
1692:                    }
1693:
1694:                // Compensate for container's insets
1695:                Insets inset = container.getInsets();
1696:                totalWidth += inset.left + inset.right;
1697:                totalHeight += inset.top + inset.bottom;
1698:
1699:                return new Dimension(totalWidth, totalHeight);
1700:            }
1701:
1702:            /**
1703:             * Determines the minimum size of the container argument using this layout.
1704:             * The minimum size is the smallest size that, if used for the container's
1705:             * size, will ensure that all components are at least as large as their
1706:             * minimum size. This method cannot guarantee that all components will be
1707:             * their minimum size. For example, if component A and component B are each
1708:             * allocate half of the container's width and component A wants to be 10
1709:             * pixels wide while component B wants to be 100 pixels wide, they cannot
1710:             * both be accommodated. Since in general components rather be larger than
1711:             * their minimum size instead of smaller, component B's request will be
1712:             * fulfilled. The minimum size of the container would be 200 pixels.
1713:             * 
1714:             * @param container
1715:             *            container being served by this layout manager
1716:             * 
1717:             * @return a dimension indicating the container's minimum size
1718:             */
1719:
1720:            public Dimension minimumLayoutSize(Container container) {
1721:                Dimension size; // Minimum size of current component
1722:                int scaledWidth = 0; // Minimum width of scalled components
1723:                int scaledHeight = 0; // Minimum height of scalled components
1724:                int fillWidth = 0; // Minimum width of fill components
1725:                int fillHeight = 0; // Minimum height of fill components
1726:                int temp; // Temporary variable used to compare sizes
1727:                int counter; // Counting variable
1728:
1729:                // Determine percentage of space allocated to fill components. This is
1730:                // one minus the sum of all scalable components.
1731:                double fillWidthRatio = 1.0;
1732:                double fillHeightRatio = 1.0;
1733:                int numFillWidth = 0;
1734:                int numFillHeight = 0;
1735:
1736:                for (counter = 0; counter < columnSpec.length; counter++)
1737:                    if ((columnSpec[counter] > 0.0)
1738:                            && (columnSpec[counter] < 1.0))
1739:                        fillWidthRatio -= columnSpec[counter];
1740:                    else if (columnSpec[counter] == FILL)
1741:                        numFillWidth++;
1742:
1743:                for (counter = 0; counter < rowSpec.length; counter++)
1744:                    if ((rowSpec[counter] > 0.0) && (rowSpec[counter] < 1.0))
1745:                        fillHeightRatio -= rowSpec[counter];
1746:                    else if (rowSpec[counter] == FILL)
1747:                        numFillHeight++;
1748:
1749:                // Adjust fill ratios to reflect number of fill rows/columns
1750:                if (numFillWidth > 1)
1751:                    fillWidthRatio /= numFillWidth;
1752:
1753:                if (numFillHeight > 1)
1754:                    fillHeightRatio /= numFillHeight;
1755:
1756:                // Cap fill ratio bottoms to 0.0
1757:                if (fillWidthRatio < 0.0)
1758:                    fillWidthRatio = 0.0;
1759:
1760:                if (fillHeightRatio < 0.0)
1761:                    fillHeightRatio = 0.0;
1762:
1763:                // Find maximum minimum size of all scaled components
1764:                ListIterator iterator = list.listIterator(0);
1765:
1766:                while (iterator.hasNext()) {
1767:                    // Get next entry
1768:                    Entry entry = (Entry) iterator.next();
1769:
1770:                    // Make sure entry is in valid rows and columns
1771:                    if ((entry.col1 < 0) || (entry.col1 >= columnSpec.length)
1772:                            || (entry.col2 >= columnSpec.length)
1773:                            || (entry.row1 < 0)
1774:                            || (entry.row1 >= rowSpec.length)
1775:                            || (entry.row2 >= rowSpec.length)) {
1776:                        // Skip the bad component
1777:                        continue;
1778:                    }
1779:
1780:                    // Get minimum size of current component
1781:                    size = entry.component.getMinimumSize();
1782:
1783:                    // Calculate portion of component that is not absolutely sized
1784:                    int scalableWidth = size.width;
1785:                    int scalableHeight = size.height;
1786:
1787:                    for (counter = entry.col1; counter <= entry.col2; counter++)
1788:                        if (columnSpec[counter] >= 1.0)
1789:                            scalableWidth -= columnSpec[counter];
1790:
1791:                    for (counter = entry.row1; counter <= entry.row2; counter++)
1792:                        if (rowSpec[counter] >= 1.0)
1793:                            scalableHeight -= rowSpec[counter];
1794:
1795:                    // ----------------------------------------------------------------------
1796:
1797:                    // Determine total percentage of scalable space that the component
1798:                    // occupies by adding the relative columns and the fill columns
1799:                    double relativeWidth = 0.0;
1800:
1801:                    for (counter = entry.col1; counter <= entry.col2; counter++) {
1802:                        // Column is scaled
1803:                        if ((columnSpec[counter] > 0.0)
1804:                                && (columnSpec[counter] < 1.0))
1805:                            // Add scaled size to relativeWidth
1806:                            relativeWidth += columnSpec[counter];
1807:                        // Column is fill
1808:                        else if ((columnSpec[counter] == FILL)
1809:                                && (fillWidthRatio != 0.0))
1810:                            // Add fill size to relativeWidth
1811:                            relativeWidth += fillWidthRatio;
1812:                    }
1813:
1814:                    // Determine the total scaled width as estimated by this component
1815:                    if (relativeWidth == 0)
1816:                        temp = 0;
1817:                    else
1818:                        temp = (int) (scalableWidth / relativeWidth + 0.5);
1819:
1820:                    // If the container needs to be bigger, make it so
1821:                    if (scaledWidth < temp)
1822:                        scaledWidth = temp;
1823:
1824:                    // ----------------------------------------------------------------------
1825:
1826:                    // Determine total percentage of scalable space that the component
1827:                    // occupies by adding the relative columns and the fill columns
1828:                    double relativeHeight = 0.0;
1829:
1830:                    for (counter = entry.row1; counter <= entry.row2; counter++) {
1831:                        // Row is scaled
1832:                        if ((rowSpec[counter] > 0.0)
1833:                                && (rowSpec[counter] < 1.0))
1834:                            // Add scaled size to relativeHeight
1835:                            relativeHeight += rowSpec[counter];
1836:                        // Row is fill
1837:                        else if ((rowSpec[counter] == FILL)
1838:                                && (fillHeightRatio != 0.0))
1839:                            // Add fill size to relativeHeight
1840:                            relativeHeight += fillHeightRatio;
1841:                    }
1842:
1843:                    // Determine the total scaled width as estimated by this component
1844:                    if (relativeHeight == 0)
1845:                        temp = 0;
1846:                    else
1847:                        temp = (int) (scalableHeight / relativeHeight + 0.5);
1848:
1849:                    // If the container needs to be bigger, make it so
1850:                    if (scaledHeight < temp)
1851:                        scaledHeight = temp;
1852:                }
1853:
1854:                // totalWidth is the scaledWidth plus the sum of all absolute widths and
1855:                // all
1856:                // preferred widths
1857:                int totalWidth = scaledWidth;
1858:
1859:                for (counter = 0; counter < columnSpec.length; counter++)
1860:                    // Is the current column an absolute size
1861:                    if (columnSpec[counter] >= 1.0)
1862:                        totalWidth += (int) (columnSpec[counter] + 0.5);
1863:                    // Is the current column a preferred size
1864:                    else if ((columnSpec[counter] == PREFERRED)
1865:                            || (columnSpec[counter] == MINIMUM)) {
1866:                        // Assume a maximum width of zero
1867:                        int maxWidth = 0;
1868:
1869:                        // Find maximum preferred width of all components completely
1870:                        // contained within this column
1871:                        iterator = list.listIterator(0);
1872:
1873:                        while (iterator.hasNext()) {
1874:                            Entry entry = (Entry) iterator.next();
1875:
1876:                            if ((entry.col1 == counter)
1877:                                    && (entry.col2 == counter)) {
1878:                                Dimension p = (columnSpec[counter] == PREFERRED) ? entry.component
1879:                                        .getPreferredSize()
1880:                                        : entry.component.getMinimumSize();
1881:
1882:                                int width = (p == null) ? 0 : p.width;
1883:
1884:                                if (maxWidth < width)
1885:                                    maxWidth = width;
1886:                            }
1887:                        }
1888:
1889:                        // Add preferred width
1890:                        totalWidth += maxWidth;
1891:                    }
1892:
1893:                // totalHeight is the scaledHeight plus the sum of all absolute heights
1894:                // and
1895:                // all preferred widths
1896:                int totalHeight = scaledHeight;
1897:
1898:                for (counter = 0; counter < rowSpec.length; counter++)
1899:                    // Is the current row an absolute size
1900:                    if (rowSpec[counter] >= 1.0)
1901:                        totalHeight += (int) (rowSpec[counter] + 0.5);
1902:                    // Is the current row a preferred size
1903:                    else if ((rowSpec[counter] == PREFERRED)
1904:                            || (rowSpec[counter] == MINIMUM)) {
1905:                        // Assume a maximum height of zero
1906:                        int maxHeight = 0;
1907:
1908:                        // Find maximum preferred height of all components completely
1909:                        // contained within this row
1910:                        iterator = list.listIterator(0);
1911:
1912:                        while (iterator.hasNext()) {
1913:                            Entry entry = (Entry) iterator.next();
1914:
1915:                            if ((entry.row1 == counter)
1916:                                    && (entry.row1 == counter)) {
1917:                                Dimension p = (rowSpec[counter] == PREFERRED) ? entry.component
1918:                                        .getPreferredSize()
1919:                                        : entry.component.getMinimumSize();
1920:
1921:                                int height = (p == null) ? 0 : p.height;
1922:
1923:                                if (maxHeight < height)
1924:                                    maxHeight = height;
1925:                            }
1926:                        }
1927:
1928:                        // Add preferred height
1929:                        totalHeight += maxHeight;
1930:                    }
1931:
1932:                // Compensate for container's insets
1933:                Insets inset = container.getInsets();
1934:                totalWidth += inset.left + inset.right;
1935:                totalHeight += inset.top + inset.bottom;
1936:
1937:                return new Dimension(totalWidth, totalHeight);
1938:            }
1939:
1940:            /**
1941:             * Adds the specified component with the specified name to the layout.
1942:             * 
1943:             * @param name
1944:             *            indicates entry's position and anchor
1945:             * @param component
1946:             *            component to add
1947:             */
1948:
1949:            public void addLayoutComponent(String name, Component component) {
1950:                addLayoutComponent(component, name);
1951:            }
1952:
1953:            // ******************************************************************************
1954:            // ** java.awt.event.LayoutManager2 methods ***
1955:            // ******************************************************************************
1956:
1957:            /**
1958:             * Adds the specified component with the specified name to the layout.
1959:             * 
1960:             * @param component
1961:             *            component to add
1962:             * @param constraint
1963:             *            indicates entry's position and alignment
1964:             */
1965:
1966:            public void addLayoutComponent(Component component,
1967:                    Object constraint) {
1968:                if (constraint instanceof  String) {
1969:
1970:                    // Olli Z. first iterate through constraints to see if any
1971:                    // names of positions need resolving
1972:                    if (columnOrRowName != null) {
1973:                        StringBuffer resolvedConstraint = new StringBuffer();
1974:                        StringTokenizer st = new StringTokenizer(
1975:                                (String) constraint, ", ");
1976:                        boolean isFirstToken = true;
1977:                        while (st.hasMoreTokens()) {
1978:                            if (!isFirstToken) {
1979:                                resolvedConstraint.append(',');
1980:                            } else {
1981:                                isFirstToken = false;
1982:                            }
1983:                            String token = st.nextToken();
1984:                            // see if is an integer (row or column)
1985:                            try {
1986:                                Integer.parseInt(token);
1987:                                // yes, so just add
1988:                                resolvedConstraint.append(token);
1989:                            } catch (NumberFormatException nfe) {
1990:                                // obviously not, this can mean two things:
1991:                                if (columnOrRowName.containsKey(token)) {
1992:                                    // 1. it is the name of a position
1993:                                    String columnOrRow = (String) columnOrRowName
1994:                                            .get(token);
1995:                                    resolvedConstraint.append(columnOrRow);
1996:                                } else {
1997:                                    // 2. it is an alignment
1998:                                    resolvedConstraint.append(token);
1999:                                }
2000:                            }
2001:                        }
2002:
2003:                        String resolvedConstraintString = resolvedConstraint
2004:                                .toString();
2005:                        // Create an entry to associate component with its constraints
2006:                        TableLayoutConstraints tableLayoutConstraints = new TableLayoutConstraints(
2007:                                resolvedConstraintString);
2008:
2009:                        // Add component and constraints to the list
2010:                        list.add(new Entry(component, tableLayoutConstraints));
2011:                    } else {
2012:                        // Create an entry to associate component with its constraints
2013:                        TableLayoutConstraints tableLayoutConstraints = new TableLayoutConstraints(
2014:                                (String) constraint);
2015:
2016:                        // Add component and constraints to the list
2017:                        list.add(new Entry(component, tableLayoutConstraints));
2018:                    }
2019:                } else if (constraint instanceof  TableLayoutConstraints) {
2020:                    // Add component and constraints to the list
2021:                    list.add(new Entry(component,
2022:                            (TableLayoutConstraints) constraint));
2023:                } else if (constraint == null)
2024:                    throw new IllegalArgumentException(
2025:                            "No constraint for the component");
2026:                else
2027:                    throw new IllegalArgumentException(
2028:                            "Cannot accept a constraint of class "
2029:                                    + constraint.getClass());
2030:            }
2031:
2032:            /**
2033:             * Removes the specified component from the layout.
2034:             * 
2035:             * @param component
2036:             *            component being removed
2037:             */
2038:
2039:            public void removeLayoutComponent(Component component) {
2040:                list.remove(component);
2041:            }
2042:
2043:            /**
2044:             * Returns the maximum dimensions for this layout given the components in
2045:             * the specified target container.
2046:             * 
2047:             * @param target
2048:             *            the component which needs to be laid out
2049:             * 
2050:             * @return unconditionally, a Dimension of Integer.MAX_VALUE by
2051:             *         Integer.MAX_VALUE since TableLayout does not limit the maximum
2052:             *         size of a container
2053:             */
2054:
2055:            public Dimension maximumLayoutSize(Container target) {
2056:                return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
2057:            }
2058:
2059:            /**
2060:             * Returns the alignment along the x axis. This specifies how the component
2061:             * would like to be aligned relative to other components. The value should
2062:             * be a number between 0 and 1 where 0 represents alignment along the
2063:             * origin, 1 is aligned the furthest away from the origin, 0.5 is centered,
2064:             * etc.
2065:             * 
2066:             * @return unconditionally, 0.5
2067:             */
2068:
2069:            public float getLayoutAlignmentX(Container parent) {
2070:                return 0.5f;
2071:            }
2072:
2073:            /**
2074:             * Returns the alignment along the y axis. This specifies how the component
2075:             * would like to be aligned relative to other components. The value should
2076:             * be a number between 0 and 1 where 0 represents alignment along the
2077:             * origin, 1 is aligned the furthest away from the origin, 0.5 is centered,
2078:             * etc.
2079:             * 
2080:             * @return unconditionally, 0.5
2081:             */
2082:
2083:            public float getLayoutAlignmentY(Container parent) {
2084:                return 0.5f;
2085:            }
2086:
2087:            /**
2088:             * Invalidates the layout, indicating that if the layout manager has cached
2089:             * information it should be discarded.
2090:             */
2091:
2092:            public void invalidateLayout(Container target) {
2093:                dirty = true;
2094:            }
2095:
2096:            // ******************************************************************************
2097:            // *** Inner Class ***
2098:            // ******************************************************************************
2099:
2100:            // The following inner class is used to bind components to their constraints
2101:            protected static class Entry extends TableLayoutConstraints {
2102:                /** ContelligentComponent bound by the constraints */
2103:                protected Component component;
2104:
2105:                /** Does the component occupy a single cell */
2106:                protected boolean singleCell;
2107:
2108:                /**
2109:                 * Constructs an Entry that binds a component to a set of constraints.
2110:                 * 
2111:                 * @param component
2112:                 *            component being bound
2113:                 * @param constranit
2114:                 *            constraints being applied
2115:                 */
2116:
2117:                public Entry(Component component,
2118:                        TableLayoutConstraints constraint) {
2119:                    super (constraint.col1, constraint.row1, constraint.col2,
2120:                            constraint.row2, constraint.hAlign,
2121:                            constraint.vAlign);
2122:
2123:                    singleCell = ((row1 == row2) && (col1 == col2));
2124:                    this .component = component;
2125:                }
2126:
2127:                /**
2128:                 * Determines whether or not two entries are equal.
2129:                 * 
2130:                 * @param object
2131:                 *            object being compared to; must be a ContelligentComponent
2132:                 *            if it is equal to this TableLayoutConstraints.
2133:                 * 
2134:                 * @return True, if the entries refer to the same component object.
2135:                 *         False, otherwise.
2136:                 */
2137:
2138:                public boolean equals(Object object) {
2139:                    boolean equal = false;
2140:
2141:                    if (object instanceof  Component) {
2142:                        Component component = (Component) object;
2143:                        equal = (this .component == component);
2144:                    }
2145:
2146:                    return equal;
2147:                }
2148:
2149:                public int hashCode() {
2150:                    return -1;
2151:                }
2152:
2153:            }
2154:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.