Source Code Cross Referenced for IzPanelLayout.java in  » Installer » IzPack » com » izforge » izpack » gui » 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 » Installer » IzPack » com.izforge.izpack.gui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id:$
0003:         * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
0004:         * 
0005:         * http://izpack.org/
0006:         * http://izpack.codehaus.org/
0007:         * 
0008:         * Copyright 2006 Klaus Bartz
0009:         * 
0010:         * Licensed under the Apache License, Version 2.0 (the "License");
0011:         * you may not use this file except in compliance with the License.
0012:         * You may obtain a copy of the License at
0013:         * 
0014:         *     http://www.apache.org/licenses/LICENSE-2.0
0015:         *     
0016:         * Unless required by applicable law or agreed to in writing, software
0017:         * distributed under the License is distributed on an "AS IS" BASIS,
0018:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0019:         * See the License for the specific language governing permissions and
0020:         * limitations under the License.
0021:         */
0022:        package com.izforge.izpack.gui;
0023:
0024:        import java.awt.Component;
0025:        import java.awt.Container;
0026:        import java.awt.Dimension;
0027:        import java.awt.Insets;
0028:        import java.awt.LayoutManager;
0029:        import java.awt.LayoutManager2;
0030:        import java.awt.Rectangle;
0031:        import java.util.ArrayList;
0032:
0033:        import javax.swing.JCheckBox;
0034:        import javax.swing.JLabel;
0035:        import javax.swing.JRadioButton;
0036:        import javax.swing.JScrollPane;
0037:        import javax.swing.JTextArea;
0038:        import javax.swing.text.JTextComponent;
0039:
0040:        import com.izforge.izpack.panels.PathSelectionPanel;
0041:        import com.izforge.izpack.util.Log;
0042:        import com.izforge.izpack.util.MultiLineLabel;
0043:
0044:        /**
0045:         * This is a special layout manager for IzPanels.
0046:         * 
0047:         * @author Klaus Bartz
0048:         * 
0049:         */
0050:        public class IzPanelLayout implements  LayoutManager, LayoutManager2,
0051:                LayoutConstants {
0052:
0053:            /** holds all the components and layout constraints. */
0054:            private ArrayList<ArrayList<IzPanelConstraints>> components = new ArrayList<ArrayList<IzPanelConstraints>>();
0055:
0056:            /** Maximum rows to handle symbolic values like NEXT_ROW in constraints. */
0057:            private int currentYPos = 0;
0058:
0059:            /** Current column to handle symbolic values like NEXT_COLUMN in constraints. */
0060:            private int currentXPos = -1;
0061:
0062:            /** Dimension object with prefered size. Will be computed new if invalidateLayout will be called. */
0063:            private Dimension prefLayoutDim;
0064:
0065:            private Dimension oldParentSize;
0066:
0067:            private Insets oldParentInsets;
0068:
0069:            private int columnFillOutRule;
0070:
0071:            private double[] overallYStretch = { -1.0, 0.0 };
0072:
0073:            protected static int[] DEFAULT_Y_GAPS = { -1, 0, 5, 5, 10, 5, 5, 5,
0074:                    5, 5, 5, 5, 5, 5, 15, 12, 9, 6, 3, 0 };
0075:
0076:            protected static int[] DEFAULT_X_GAPS = { -1, 0, 0, 0, 0, 0, 10,
0077:                    10, 10, 10, 10, 10, 10, 15, 12, 9, 6, 3, 0 };
0078:
0079:            protected static int[] DEFAULT_X_ALIGNMENT = { LEFT, LEFT, LEFT,
0080:                    LEFT };
0081:
0082:            protected static int[] DEFAULT_Y_ALIGNMENT = { CENTER, CENTER,
0083:                    CENTER, CENTER };
0084:
0085:            /** Array with some default constraints. */
0086:            private static IzPanelConstraints DEFAULT_CONSTRAINTS[] = {
0087:            // Default constraints for labels.
0088:                    new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT,
0089:                            DEFAULT_LABEL_ALIGNMENT, NEXT_COLUMN, CURRENT_ROW,
0090:                            1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP, 0.0, 0.0),
0091:                    // Default constraints for text fields.
0092:                    new IzPanelConstraints(DEFAULT_TEXT_ALIGNMENT,
0093:                            DEFAULT_TEXT_ALIGNMENT, NEXT_COLUMN, CURRENT_ROW,
0094:                            1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP, 0.0, 0.0),
0095:                    // Default constraints for other controls using two columns if possible.
0096:                    new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT,
0097:                            DEFAULT_CONTROL_ALIGNMENT, NEXT_COLUMN,
0098:                            CURRENT_ROW, 1, 1, AUTOMATIC_GAP, AUTOMATIC_GAP,
0099:                            0.0, 0.0),
0100:                    // Default constraints for full line controls.
0101:                    new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT,
0102:                            DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW,
0103:                            Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP,
0104:                            AUTOMATIC_GAP, FULL_LINE_STRETCH, 0.0),
0105:                    // Default constraints for constraints for controls/container which are variable in x
0106:                    // and y dimension.
0107:                    new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT,
0108:                            DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW,
0109:                            Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP,
0110:                            AUTOMATIC_GAP, FULL_LINE_STRETCH,
0111:                            FULL_COLUMN_STRETCH),
0112:                    // Default constraints for x filler.
0113:                    new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT,
0114:                            DEFAULT_LABEL_ALIGNMENT, NEXT_COLUMN, CURRENT_ROW,
0115:                            1, 1, 0, 0, 0.0, 0.0),
0116:                    // Default constraints for y filler.
0117:                    new IzPanelConstraints(DEFAULT_LABEL_ALIGNMENT,
0118:                            DEFAULT_LABEL_ALIGNMENT, 0, NEXT_ROW, 1, 1, 0, 0,
0119:                            0.0, 0.0),
0120:                    // Default constraints for other controls using the full line.
0121:                    new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT,
0122:                            DEFAULT_CONTROL_ALIGNMENT, 0, NEXT_ROW,
0123:                            Byte.MAX_VALUE, Byte.MAX_VALUE, AUTOMATIC_GAP,
0124:                            AUTOMATIC_GAP, FULL_LINE_STRETCH, 0.0),
0125:
0126:            };
0127:
0128:            /** Anchor to be used for the controls in all panels. */
0129:            private static int ANCHOR = CENTER;
0130:
0131:            private static int X_STRETCH_TYPE = RELATIVE_STRETCH;
0132:
0133:            private static int Y_STRETCH_TYPE = RELATIVE_STRETCH;
0134:
0135:            private static double FULL_LINE_STRETCH_DEFAULT = 1.0;
0136:
0137:            private static double FULL_COLUMN_STRETCH_DEFAULT = 1.0;
0138:
0139:            private static int DEFAULT_TEXTFIELD_LENGTH = 12;
0140:
0141:            private static final int[][] GAP_INTERMEDIAER_LOOKUP = {
0142:                    { LABEL_GAP, LABEL_TO_TEXT_GAP, LABEL_TO_CONTROL_GAP,
0143:                            LABEL_GAP, LABEL_TO_CONTROL_GAP, LABEL_GAP,
0144:                            LABEL_GAP },
0145:                    { TEXT_TO_LABEL_GAP, TEXT_GAP, TEXT_TO_CONTROL_GAP,
0146:                            TEXT_TO_LABEL_GAP, TEXT_TO_CONTROL_GAP, TEXT_GAP,
0147:                            TEXT_GAP },
0148:                    { CONTROL_TO_LABEL_GAP, CONTROL_TO_TEXT_GAP, CONTROL_GAP,
0149:                            CONTROL_TO_LABEL_GAP, CONTROL_GAP, CONTROL_GAP,
0150:                            CONTROL_GAP },
0151:                    { LABEL_GAP, LABEL_TO_TEXT_GAP, LABEL_TO_CONTROL_GAP,
0152:                            LABEL_GAP, LABEL_TO_CONTROL_GAP, LABEL_GAP,
0153:                            LABEL_GAP },
0154:                    { CONTROL_TO_LABEL_GAP, CONTROL_TO_TEXT_GAP, CONTROL_GAP,
0155:                            CONTROL_TO_LABEL_GAP, CONTROL_GAP, CONTROL_GAP,
0156:                            CONTROL_GAP },
0157:                    { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP,
0158:                            NO_GAP },
0159:                    { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP,
0160:                            NO_GAP },
0161:                    { NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP, NO_GAP,
0162:                            NO_GAP } };
0163:
0164:            /**
0165:             * Default constructor
0166:             */
0167:            public IzPanelLayout() {
0168:                this (NO_FILL_OUT_COLUMN);
0169:            }
0170:
0171:            /**
0172:             * Creates an layout manager which consider the given column fill out rule. Valid rules are
0173:             * NO_FILL_OUT_COLUMN, FILL_OUT_COLUMN_WIDTH, FILL_OUT_HEIGHT and FILL_OUT_COLUMN_SIZE
0174:             * 
0175:             * @param colFillOutRule
0176:             */
0177:            public IzPanelLayout(int colFillOutRule) {
0178:                super ();
0179:                columnFillOutRule = colFillOutRule;
0180:            }
0181:
0182:            /**
0183:             * Returns the y gap for the given constraint dependant on the next y constraint.
0184:             * 
0185:             * @param curConst constraint of the component for which the gap should be returnd
0186:             * @param nextYConst constraint of the component which is the next in y direction
0187:             * @return the y gap
0188:             */
0189:            private static int getYGap(IzPanelConstraints curConst,
0190:                    IzPanelConstraints nextYConst) {
0191:
0192:                Class nextClass = (nextYConst != null) ? nextYConst.component
0193:                        .getClass() : FillerComponent.class;
0194:                int interId = GAP_INTERMEDIAER_LOOKUP[getIntermediarId(
0195:                        curConst.component.getClass(), null)][getIntermediarId(
0196:                        nextClass, null)];
0197:                if (interId < 0)
0198:                    interId = -interId;
0199:                return (DEFAULT_Y_GAPS[interId]);
0200:
0201:            }
0202:
0203:            /**
0204:             * Returns the x gap for the given constraint dependant on the next x constraint.
0205:             * 
0206:             * @param curConst constraint of the component for which the gap should be returnd
0207:             * @param nextXConst constraint of the component which is the next in x direction
0208:             * @return the x gap
0209:             */
0210:            private static int getXGap(IzPanelConstraints curConst,
0211:                    IzPanelConstraints nextXConst) {
0212:
0213:                Class nextClass = (nextXConst != null) ? nextXConst.component
0214:                        .getClass() : FillerComponent.class;
0215:                int interId = GAP_INTERMEDIAER_LOOKUP[getIntermediarId(
0216:                        curConst.component.getClass(), null)][getIntermediarId(
0217:                        nextClass, null)];
0218:                if (interId < 0)
0219:                    interId = -interId;
0220:                return (DEFAULT_X_GAPS[interId]);
0221:
0222:            }
0223:
0224:            /**
0225:             * Returns an index depending on the class type. Only for internal use.
0226:             * 
0227:             * @param clazz class for which the index should be returned
0228:             * @param comp component for which the index should be returned
0229:             * @return an index depending on the class type
0230:             */
0231:            private static int getIntermediarId(Class clazz, Component comp) {
0232:
0233:                if (comp != null) {
0234:                    if (MultiLineLabel.class.isAssignableFrom(clazz)
0235:                            || LabelFactory.FullLineLabel.class
0236:                                    .isAssignableFrom(clazz))
0237:                        return (FULL_LINE_COMPONENT_CONSTRAINT);
0238:                    if (PathSelectionPanel.class.isAssignableFrom(clazz)
0239:                            || JCheckBox.class.isAssignableFrom(clazz)
0240:                            || JRadioButton.class.isAssignableFrom(clazz))
0241:                        return (FULL_LINE_CONTROL_CONSTRAINT);
0242:                    if (FillerComponent.class.isAssignableFrom(clazz)
0243:                            || javax.swing.Box.Filler.class
0244:                                    .isAssignableFrom(clazz)) {
0245:                        Dimension size = comp.getPreferredSize();
0246:                        if (size.height >= Short.MAX_VALUE || size.height <= 0) {
0247:                            size.height = 0;
0248:                            comp.setSize(size);
0249:                            return (XDUMMY_CONSTRAINT);
0250:                        } else if (size.width >= Short.MAX_VALUE
0251:                                || size.width <= 0) {
0252:                            size.width = 0;
0253:                            comp.setSize(size);
0254:                            return (YDUMMY_CONSTRAINT);
0255:                        }
0256:                    }
0257:                }
0258:                if (JScrollPane.class.isAssignableFrom(clazz))
0259:                    return (XY_VARIABLE_CONSTRAINT);
0260:                if (JLabel.class.isAssignableFrom(clazz))
0261:                    return (LABEL_CONSTRAINT);
0262:                if (JTextComponent.class.isAssignableFrom(clazz))
0263:                    return (TEXT_CONSTRAINT);
0264:                if (FillerComponent.class.isAssignableFrom(clazz))
0265:                    return (XDUMMY_CONSTRAINT);
0266:                if (javax.swing.Box.Filler.class.isAssignableFrom(clazz))
0267:                    return (XDUMMY_CONSTRAINT);
0268:                return (CONTROL_CONSTRAINT); // Other controls.
0269:            }
0270:
0271:            /*
0272:             * (non-Javadoc)
0273:             * 
0274:             * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, java.awt.Component)
0275:             */
0276:            public void addLayoutComponent(String name, Component comp) {
0277:                // Has to be implemented, but not supported in this class.
0278:            }
0279:
0280:            /*
0281:             * (non-Javadoc)
0282:             * 
0283:             * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.Component)
0284:             */
0285:            public void removeLayoutComponent(Component comp) {
0286:                // Has to be implemented, but not supported in this class.
0287:            }
0288:
0289:            /*
0290:             * (non-Javadoc)
0291:             * 
0292:             * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
0293:             */
0294:            public Dimension minimumLayoutSize(Container parent) {
0295:                return preferredLayoutSize(parent);
0296:            }
0297:
0298:            /*
0299:             * (non-Javadoc)
0300:             * 
0301:             * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
0302:             */
0303:            public Dimension preferredLayoutSize(Container parent) {
0304:                return (determineSize());
0305:            }
0306:
0307:            /**
0308:             * Method which determine minimum with and height of this layout. The size will be stored after
0309:             * cumputing in a class member. With a call to invalidateLayout this will be deleted and at the
0310:             * next call to this method the values are computed again.
0311:             * 
0312:             * @return current minimum size
0313:             */
0314:            private Dimension determineSize() {
0315:                if (prefLayoutDim == null) {
0316:                    int width = minimumAllColumnsWidth();
0317:                    int height = minimumOverallHeight();
0318:                    prefLayoutDim = new Dimension(width, height);
0319:                }
0320:                return (Dimension) (prefLayoutDim.clone());
0321:            }
0322:
0323:            /**
0324:             * Returns the number of rows that need to be laid out.
0325:             * 
0326:             * @return the number of rows that need to be laid out
0327:             */
0328:            private int rows() {
0329:                int maxRows = 0;
0330:                for (Object component : components) {
0331:                    int curRows = ((ArrayList) component).size();
0332:                    if (curRows > maxRows) {
0333:                        maxRows = curRows;
0334:                    }
0335:
0336:                }
0337:                return (maxRows);
0338:            }
0339:
0340:            /**
0341:             * Returns the number of columns that need to be laid out.
0342:             * 
0343:             * @return the number of columns that need to be laid out
0344:             */
0345:            private int columns() {
0346:                return (components.size());
0347:            }
0348:
0349:            /**
0350:             * Minimum height of all rows.
0351:             * 
0352:             * @return minimum height of all rows
0353:             */
0354:            private int minimumOverallHeight() {
0355:                int height = 0;
0356:
0357:                for (int i = 0; i < rows(); i++) {
0358:                    height += rowHeight(i);
0359:                }
0360:
0361:                return (height);
0362:            }
0363:
0364:            /**
0365:             * Measures and returns the minimum height required to render the components in the indicated
0366:             * row.
0367:             * 
0368:             * @param row the index of the row to measure
0369:             * @return minimum height of a row
0370:             */
0371:            private int rowHeight(int row) {
0372:                int height = 0;
0373:                for (int i = 0; i < components.size(); ++i) {
0374:                    int curHeight = getCellSize(i, row, null).height;
0375:                    if (curHeight > height)
0376:                        height = curHeight;
0377:                }
0378:                return (height);
0379:            }
0380:
0381:            /**
0382:             * Measures and returns the minimum height required to render the components in the indicated
0383:             * row.
0384:             * 
0385:             * @param row the index of the row to measure
0386:             * @param maxOverallHeight
0387:             * @param minOverallHeight
0388:             * @return minimum height of a row
0389:             */
0390:            private int rowHeight(int row, int minOverallHeight,
0391:                    int maxOverallHeight) {
0392:                // First determine minimum row height and whether there is a y stretch or not.
0393:                int height = 0;
0394:                double[] yStretch = getOverallYStretch();
0395:                if (yStretch[0] <= 0.0)
0396:                    return (rowHeight(row));
0397:                double maxStretch = 0.0;
0398:                double[] stretchParts = new double[components.size()];
0399:                for (int i = 0; i < components.size(); ++i) {
0400:                    IzPanelConstraints constraints = getConstraints(i, row);
0401:                    double stretch = constraints.getYStretch();
0402:                    stretchParts[i] = stretch;
0403:                    if (stretch > maxStretch)
0404:                        maxStretch = stretch;
0405:                    int curHeight = getCellSize(i, row, constraints).height;
0406:                    if (curHeight > height)
0407:                        height = curHeight;
0408:                }
0409:                if (maxOverallHeight <= minOverallHeight)
0410:                    return (height);
0411:                // We have a y stretch and place. Let us disperse it.
0412:                int pixels = (int) (maxOverallHeight - yStretch[1] - minOverallHeight);
0413:                int stretchPart = (int) (pixels * maxStretch);
0414:                if (stretchPart > 0) {
0415:                    for (int i = 0; i < components.size(); ++i) {
0416:                        if (stretchParts[i] < 0.00000001)
0417:                            continue;
0418:                        IzPanelConstraints constraints = getConstraints(i, row);
0419:                        Dimension size = constraints.component
0420:                                .getPreferredSize();
0421:                        if (size.height + stretchPart * stretchParts[i] < height)
0422:                            size.height = (int) (height + stretchPart
0423:                                    * stretchParts[i]);
0424:                        else
0425:                            size.height = height + stretchPart;
0426:                        if (constraints.component instanceof  JScrollPane) { // This is a hack for text areas which uses word wrap. At tests
0427:                            // they have a preferred width of 100 pixel which breaks the layout.
0428:
0429:                            if (((JScrollPane) constraints.component)
0430:                                    .getViewport().getView() instanceof  JTextArea) {
0431:                                if (((JTextArea) ((JScrollPane) constraints.component)
0432:                                        .getViewport().getView()).getLineWrap())
0433:                                    size.width = 1000;
0434:                            }
0435:                        }
0436:                        constraints.component.setPreferredSize(size);
0437:
0438:                    }
0439:                    height += stretchPart;
0440:
0441:                }
0442:                return (height);
0443:            }
0444:
0445:            /**
0446:             * Returns the sum of the maximum y stretch of each row.
0447:             * 
0448:             * @return the sum of the maximum y stretch of each row
0449:             */
0450:            private double[] getOverallYStretch() {
0451:                if (overallYStretch[0] >= 0.0)
0452:                    return (overallYStretch); // Stretch already computed.
0453:                overallYStretch[0] = 0.0;
0454:                for (int row = 0; row < rows(); ++row) {
0455:                    double maxStretch = 0.0;
0456:                    double maxGap = 0.0;
0457:                    for (int i = 0; i < components.size(); ++i) {
0458:                        IzPanelConstraints constraints = getConstraints(i, row);
0459:                        resolveDefaultSettings(i, row);
0460:                        if (constraints.getYStretch() == FULL_COLUMN_STRETCH)
0461:                            constraints.setYStretch(IzPanelLayout
0462:                                    .getFullColumnStretch());
0463:                        double curStretch = constraints.getYStretch();
0464:                        if (curStretch > maxStretch)
0465:                            maxStretch = curStretch;
0466:                        double curYGap = constraints.getYGap();
0467:                        if (curYGap > maxGap)
0468:                            maxGap = curYGap;
0469:                    }
0470:                    overallYStretch[0] += maxStretch;
0471:                    overallYStretch[1] += maxGap;
0472:                }
0473:                // Modify y stretch depending on the current Y-Stretch type.
0474:                if (overallYStretch[0] > 0.0) {
0475:                    switch (IzPanelLayout.getYStretchType()) {
0476:                    case RELATIVE_STRETCH:
0477:                        break;
0478:                    case ABSOLUTE_STRETCH:
0479:                        overallYStretch[0] = 1.0;
0480:                        break;
0481:                    case NO_STRETCH:
0482:                    default:
0483:                        overallYStretch[0] = 0.0;
0484:                        break;
0485:                    }
0486:                }
0487:
0488:                return (overallYStretch);
0489:            }
0490:
0491:            /**
0492:             * Measures and returns the minimum size required to render the component in the indicated row
0493:             * and column. The constraints can be null.
0494:             * 
0495:             * @param row the index of the row to measure
0496:             * @param column the column of the component
0497:             * @param constraints constraints of current component
0498:             * @return size of the given cell
0499:             */
0500:            private Dimension getCellSize(int column, int row,
0501:                    IzPanelConstraints constraints) {
0502:                Dimension retval = new Dimension();
0503:                Component component;
0504:
0505:                try {
0506:                    if (constraints == null)
0507:                        constraints = getConstraints(column, row);
0508:                    if (constraints != null) {
0509:                        component = constraints.component;
0510:                        // Some components returns the needed size with getPreferredSize
0511:                        // some with getMinimumSize. Therefore following code...
0512:                        Dimension dim = component.getPreferredSize();
0513:                        Dimension dim2 = component.getMinimumSize();
0514:                        retval.height = (dim.height > dim2.height) ? dim.height
0515:                                : dim2.height;
0516:                        retval.width = (dim.width > dim2.width) ? dim.width
0517:                                : dim2.width;
0518:                        if (component instanceof  JScrollPane) { // But at a JScrollPane we have to use the minimum size because
0519:                            // preferred size is the size of the view.
0520:                            retval.height = dim2.height;
0521:                            retval.width = dim2.width;
0522:                        }
0523:                        if (needsReEvaluation(component))
0524:                            retval.width = 0;
0525:
0526:                    }
0527:                } catch (Throwable exception) {
0528:                    // ----------------------------------------------------
0529:                    // we might get an exception if one of the array list is
0530:                    // shorter, because we index out of bounds. If there
0531:                    // is nothing there then the height is 0, nothing
0532:                    // further to worry about!
0533:                    // ----------------------------------------------------
0534:                }
0535:
0536:                return (retval);
0537:            }
0538:
0539:            /**
0540:             * Returns the minimum width of the column requested. This contains not the gaps.
0541:             * 
0542:             * @param column the columns to measure
0543:             * 
0544:             * @return the minimum width required to fit the components in this column
0545:             */
0546:            private int minimumColumnWidth(int column) {
0547:                int maxWidth = 0;
0548:                Dimension[] cs = new Dimension[rows()];
0549:                for (int i = 0; i < rows(); ++i) {
0550:                    IzPanelConstraints constraints = getConstraints(column, i);
0551:                    cs[i] = getCellSize(column, i, constraints);
0552:                    if (constraints.getXWeight() <= 1)
0553:                        if (maxWidth < cs[i].width)
0554:                            maxWidth = cs[i].width;
0555:                }
0556:                if (maxWidth == 0) {
0557:                    for (int i = 0; i < rows(); ++i) {
0558:                        if (maxWidth < cs[i].width)
0559:                            maxWidth = cs[i].width;
0560:                    }
0561:                }
0562:                return (maxWidth);
0563:            }
0564:
0565:            /**
0566:             * Returns the minimum width needed by all columns.
0567:             * 
0568:             * @return the minimum width needed by all columns
0569:             */
0570:            private int minimumAllColumnsWidth() {
0571:                int width = 0;
0572:                for (int i = 0; i < this .components.size(); ++i)
0573:                    width += minimumColumnWidth(i);
0574:                return (width);
0575:            }
0576:
0577:            /**
0578:             * Returns the constraint object of the component at the given place.
0579:             * 
0580:             * @param col column of the component
0581:             * @param row row of the component
0582:             * @return the constraint object of the component at the given place
0583:             */
0584:            private IzPanelConstraints getConstraints(int col, int row) {
0585:                if (col >= columns() || row >= rows())
0586:                    return (null);
0587:                Object obj = components.get(col);
0588:                if (obj != null && obj instanceof  ArrayList) {
0589:                    try {
0590:                        obj = (components.get(col)).get(row);
0591:                    } catch (Throwable t) {
0592:                        obj = null;
0593:                    }
0594:                    if (obj != null)
0595:                        return ((IzPanelConstraints) obj);
0596:                    // no constraints is possible if no valid component
0597:                    // was added under this component.
0598:                    // Put dummy components into the array.
0599:
0600:                    ArrayList<IzPanelConstraints> colA = components.get(col);
0601:                    for (int curRow = colA.size(); row >= curRow; ++curRow) {
0602:
0603:                        IzPanelConstraints currentConst = IzPanelLayout
0604:                                .getDefaultConstraint(XDUMMY_CONSTRAINT);
0605:                        currentConst.setXPos(col);
0606:                        currentConst.setYPos(curRow);
0607:                        currentConst.component = new FillerComponent();
0608:                        try {
0609:                            (components.get(col)).add(row, currentConst);
0610:                        } catch (Throwable t) {
0611:                            return (null);
0612:                        }
0613:                    }
0614:                    return (getConstraints(col, row));
0615:                }
0616:                return (null);
0617:            }
0618:
0619:            private int getAdaptedXPos(int xpos, int curWidth,
0620:                    Dimension curDim, IzPanelConstraints currentConst) {
0621:                int adaptedXPos = xpos;// currentConst.getXGap();
0622:                if ((columnFillOutRule & FILL_OUT_COLUMN_WIDTH) > 0)
0623:                    return (adaptedXPos);
0624:                switch (currentConst.getXCellAlignment()) {
0625:                case LEFT:
0626:                    break;
0627:                case RIGHT:
0628:                    adaptedXPos += curWidth - curDim.width;
0629:                    break;
0630:                case CENTER:
0631:                default:
0632:                    adaptedXPos += (curWidth - curDim.width) / 2;
0633:                    break;
0634:
0635:                }
0636:                return (adaptedXPos);
0637:            }
0638:
0639:            private int getAdaptedYPos(int ypos, int curHeight,
0640:                    Dimension curDim, IzPanelConstraints currentConst) {
0641:                int adaptedYPos = ypos;// + currentConst.getYGap();
0642:                if ((columnFillOutRule & FILL_OUT_COLUMN_HEIGHT) > 0)
0643:                    return (adaptedYPos);
0644:                int height = curDim.height;
0645:                switch (currentConst.getYCellAlignment()) {
0646:                case TOP:
0647:                    break;
0648:                case BOTTOM:
0649:                    adaptedYPos += curHeight - height;
0650:                    break;
0651:                case CENTER:
0652:                default:
0653:                    adaptedYPos += (curHeight - height) / 2;
0654:                    break;
0655:
0656:                }
0657:                if (adaptedYPos < ypos)
0658:                    return (ypos);
0659:                return (adaptedYPos);
0660:            }
0661:
0662:            private void resolveDefaultSettings(int col, int row) {
0663:                IzPanelConstraints currentConst = getConstraints(col, row);
0664:                IzPanelConstraints nextYConst = getConstraints(col, row + 1);
0665:                IzPanelConstraints nextXConst = getConstraints(col + 1, row);
0666:                if (currentConst == null)
0667:                    return;
0668:                int gap = currentConst.getYGap();
0669:                if (gap == AUTOMATIC_GAP) { // Automatic gap; determine now.
0670:                    currentConst.setYGap(getYGap(currentConst, nextYConst));
0671:                } else if (gap < 0) {
0672:                    currentConst.setYGap(DEFAULT_Y_GAPS[-gap]);
0673:                }
0674:                gap = currentConst.getXGap();
0675:                if (gap == AUTOMATIC_GAP) { // Automatic gap; determine now.
0676:                    currentConst.setXGap(getXGap(currentConst, nextXConst));
0677:                } else if (gap < 0) {
0678:                    currentConst.setXGap(DEFAULT_X_GAPS[-gap]);
0679:                }
0680:
0681:                if (currentConst.getXCellAlignment() < 0) {
0682:                    currentConst
0683:                            .setXCellAlignment(DEFAULT_X_ALIGNMENT[-currentConst
0684:                                    .getXCellAlignment()]);
0685:                }
0686:                if (currentConst.getYCellAlignment() < 0) {
0687:                    currentConst
0688:                            .setYCellAlignment(DEFAULT_Y_ALIGNMENT[-currentConst
0689:                                    .getYCellAlignment()]);
0690:                }
0691:
0692:            }
0693:
0694:            /*
0695:             * (non-Javadoc)
0696:             * 
0697:             * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
0698:             */
0699:            public void layoutContainer(Container parent) {
0700:                if (!needNewLayout(parent)) {
0701:                    fastLayoutContainer(parent);
0702:                    return;
0703:                }
0704:                prefLayoutDim = null;
0705:                preferredLayoutSize(parent);
0706:                Dimension realSizeDim = parent.getSize();
0707:                Log.getInstance().addDebugMessage(
0708:                        "IzPanelLayout.layoutContainer parent size: {0}",
0709:                        new String[] { parent.getSize().toString() },
0710:                        "LayoutTrace", null);
0711:                Insets insets = parent.getInsets();
0712:
0713:                int rowHeight = 0;
0714:                int onceAgain = 0;
0715:                int[] generellOffset = new int[] { 0, 0 };
0716:                // int generellYOffset = 0;
0717:                // int generellXOffset = 0;
0718:                int maxWidth = 0;
0719:                int overallHeight = 0;
0720:                int anchorNeedsReEval = 0;
0721:                Rectangle curRect = new Rectangle();
0722:                int minOverallHeight = minimumOverallHeight();
0723:                int maxOverallHeight = realSizeDim.height - insets.top
0724:                        - insets.bottom;
0725:                while (anchorNeedsReEval < 2) {
0726:                    int ypos = insets.top;
0727:
0728:                    int row = 0;
0729:                    int minWidth = 0xffff;
0730:                    int minHeight = 0xffff;
0731:                    maxWidth = 0;
0732:                    overallHeight = 0;
0733:                    while (row < rows()) {
0734:                        int outerRowHeight = 0;
0735:                        int xpos = insets.left;
0736:                        // rowHeight = rowHeight(row, minOverallHeight, maxOverallHeight);
0737:                        int col = 0;
0738:                        IzPanelConstraints[] colConstraints = new IzPanelConstraints[columns()];
0739:                        int usedWidth = 0;
0740:                        Dimension curDim;
0741:                        while (col < columns()) {
0742:                            if (col == 0)
0743:                                rowHeight = rowHeight(row, minOverallHeight,
0744:                                        maxOverallHeight);
0745:                            IzPanelConstraints currentConst = getConstraints(
0746:                                    col, row);
0747:                            colConstraints[col] = currentConst;
0748:                            Component currentComp = currentConst.component;
0749:                            curDim = currentComp.getPreferredSize();
0750:                            int curWidth = minimumColumnWidth(col);
0751:                            col++;
0752:                            if (currentConst.getXWeight() > 1) {
0753:                                int weight = currentConst.getXWeight();
0754:                                while (weight > 1 && col < columns()) {
0755:                                    colConstraints[col] = getConstraints(col,
0756:                                            row);
0757:                                    if (!(colConstraints[col].component instanceof  FillerComponent))
0758:                                        break;
0759:                                    curWidth += minimumColumnWidth(col);
0760:                                    col++;
0761:                                    weight--;
0762:                                }
0763:                            }
0764:                            // width known
0765:                            int adaptedXPos = getAdaptedXPos(xpos, curWidth,
0766:                                    curDim, currentConst);
0767:                            int adaptedYPos = getAdaptedYPos(ypos, rowHeight,
0768:                                    curDim, currentConst);
0769:                            // currentComp.setBounds(adaptedXPos + generellOffset[0], adaptedYPos
0770:                            // + currentConst.getYGap() + generellOffset[1], curWidth, rowHeight);
0771:                            // + generellOffset[1], curWidth, rowHeight);
0772:                            int useWidth = curDim.width;
0773:                            int useHeight = curDim.height;
0774:                            if ((columnFillOutRule & FILL_OUT_COLUMN_WIDTH) > 0)
0775:                                useWidth = curWidth;
0776:                            if ((columnFillOutRule & FILL_OUT_COLUMN_HEIGHT) > 0)
0777:                                useHeight = rowHeight;
0778:                            if (curWidth < useWidth)
0779:                                useWidth = curWidth;
0780:                            // First setBounds using computed offsets and the size which exist previous.
0781:                            currentComp.setBounds(adaptedXPos
0782:                                    + generellOffset[0], adaptedYPos
0783:                                    + generellOffset[1], useWidth, useHeight);
0784:                            currentComp.getBounds(curRect);
0785:                            if (curRect.height > 100)
0786:                                curRect.height = useHeight;
0787:                            if (!(currentComp instanceof  FillerComponent)) {
0788:                                if (curRect.x < minWidth)
0789:                                    minWidth = curRect.x;
0790:                                if (curRect.y < minHeight)
0791:                                    minHeight = curRect.y;
0792:                            }
0793:                            int curMax = (int) curRect.getMaxX();
0794:                            if (curMax - minWidth > maxWidth)
0795:                                maxWidth = curMax - minWidth;
0796:                            curMax = (int) curRect.getMaxY();
0797:                            currentConst.setBounds(curRect);
0798:                            if (curMax - minHeight > overallHeight)
0799:                                overallHeight = curMax - minHeight;
0800:                            // xpos += currentComp.getSize().width + currentConst.getXGap();
0801:                            xpos += curWidth + currentConst.getXGap();
0802:                            usedWidth += curWidth;
0803:                            if (outerRowHeight < rowHeight
0804:                                    + currentConst.getYGap())
0805:                                outerRowHeight = rowHeight
0806:                                        + currentConst.getYGap();
0807:                        }
0808:                        // Now we have made a row, but may be there are place across or/and a component
0809:                        // needs a reevaluation.
0810:                        double rowStretch = 0.0;
0811:                        int i;
0812:                        // Determine hole stretch of this row.
0813:                        for (i = 0; i < colConstraints.length; ++i) {
0814:                            if (colConstraints[i].getXStretch() == FULL_LINE_STRETCH)
0815:                                colConstraints[i].setXStretch(IzPanelLayout
0816:                                        .getFullLineStretch());
0817:                            rowStretch += colConstraints[i].getXStretch();
0818:                        }
0819:                        // Modify rowStretch depending on the current X-Stretch type.
0820:                        if (rowStretch > 0.0) {
0821:                            switch (IzPanelLayout.getXStretchType()) {
0822:                            case RELATIVE_STRETCH:
0823:                                break;
0824:                            case ABSOLUTE_STRETCH:
0825:                                rowStretch = 1.0;
0826:                                break;
0827:                            case NO_STRETCH:
0828:                            default:
0829:                                rowStretch = 0.0;
0830:                                break;
0831:                            }
0832:                        }
0833:                        if (realSizeDim.width - insets.right != xpos
0834:                                && rowStretch > 0.0) { // Compute only if there is space to share and at least one control should be
0835:                            // stretched.
0836:                            int pixel = realSizeDim.width - insets.right - xpos; // How many pixel we
0837:                            // can use for stretching.
0838:                            int offset = 0;
0839:                            int oldOnceAgain = onceAgain;
0840:                            for (i = 0; i < colConstraints.length; ++i) {
0841:                                int curPixel = (int) ((colConstraints[i]
0842:                                        .getXStretch() / rowStretch) * pixel);
0843:
0844:                                Rectangle curBounds = colConstraints[i].component
0845:                                        .getBounds();
0846:                                // The width of some components differ from time to time. E.g. a JScrollPane
0847:                                // with a JEditorPane as viewport has sometimes the minimum column width and
0848:                                // some times the width of the scroll bar. Therefore we use the minimum
0849:                                // column width.
0850:                                int curWidth = this .minimumColumnWidth(i);
0851:                                if (curBounds.width < curWidth)
0852:                                    curBounds.width = curWidth;
0853:                                int newWidth = curPixel + curBounds.width;
0854:                                Log
0855:                                        .getInstance()
0856:                                        .addDebugMessage(
0857:                                                "IzPanelLayout.layoutContainer resize bounds for {2}|{3} old width {0} new width {1}",
0858:                                                new String[] {
0859:                                                        Integer
0860:                                                                .toString(curBounds.width),
0861:                                                        Integer
0862:                                                                .toString(newWidth),
0863:                                                        Integer.toString(row),
0864:                                                        Integer.toString(i) },
0865:                                                "LayoutTrace", null);
0866:                                colConstraints[i].component.setBounds(
0867:                                        curBounds.x + offset, curBounds.y,
0868:                                        newWidth, curBounds.height);
0869:                                colConstraints[i].component.getBounds(curRect);
0870:                                if (curRect.x > 0 && curRect.x < minWidth)
0871:                                    minWidth = curRect.x;
0872:                                if (curRect.y > 0 && curRect.y < minHeight)
0873:                                    minHeight = curRect.y;
0874:                                int curMax = (int) curRect.getMaxX();
0875:                                if (curMax - minWidth > maxWidth)
0876:                                    maxWidth = curMax - minWidth;
0877:                                curMax = (int) curRect.getMaxY();
0878:                                colConstraints[i].setBounds(curRect);
0879:
0880:                                if (curMax - minHeight > overallHeight)
0881:                                    overallHeight = curMax - minHeight;
0882:
0883:                                Log
0884:                                        .getInstance()
0885:                                        .addDebugMessage(
0886:                                                "IzPanelLayout.layoutContainer resize bounds for {2}|{3} ({0}): {1}",
0887:                                                new String[] {
0888:                                                        colConstraints[i].component
0889:                                                                .getClass()
0890:                                                                .getName(),
0891:                                                        curRect.toString(),
0892:                                                        Integer.toString(row),
0893:                                                        Integer.toString(i) },
0894:                                                "LayoutTrace", null);
0895:
0896:                                Log
0897:                                        .getInstance()
0898:                                        .addDebugMessage(
0899:                                                "IzPanelLayout.layoutContainer resize bounds for {2}|{3}: maxWidth = {0} maxHeight = {1}",
0900:                                                new String[] {
0901:                                                        Integer
0902:                                                                .toString(maxWidth),
0903:                                                        Integer
0904:                                                                .toString(overallHeight),
0905:                                                        Integer.toString(row),
0906:                                                        Integer.toString(i) },
0907:                                                "LayoutTrace", null);
0908:
0909:                                offset += curPixel;
0910:                                if (needsReEvaluation(colConstraints[i].component)) {
0911:                                    if (oldOnceAgain == onceAgain)
0912:                                        onceAgain++;
0913:                                }
0914:                            }
0915:
0916:                        }
0917:                        // Seems so that height has changed. Reevaluate only one time else it is possible
0918:                        // to go in a endless loop.
0919:
0920:                        if (onceAgain == 1)
0921:                            continue;
0922:                        onceAgain = 0;
0923:                        ypos += outerRowHeight;
0924:                        row++;
0925:                    }
0926:                    anchorNeedsReEval += resolveGenerellOffsets(generellOffset,
0927:                            realSizeDim, insets, maxWidth, overallHeight);
0928:
0929:                }
0930:            }
0931:
0932:            private void fastLayoutContainer(Container parent) {
0933:                for (int row = 0; row < rows(); ++row) {
0934:                    for (int col = 0; col < columns(); ++col) {
0935:                        IzPanelConstraints currentConst = getConstraints(col,
0936:                                row);
0937:                        if (currentConst != null) {
0938:                            Log
0939:                                    .getInstance()
0940:                                    .addDebugMessage(
0941:                                            "IzPanelLayout.fastLayoutContainer bounds: {0}",
0942:                                            new String[] { currentConst
0943:                                                    .getBounds().toString() },
0944:                                            "LayoutTrace", null);
0945:                            currentConst.component.setBounds(currentConst
0946:                                    .getBounds());
0947:                        }
0948:
0949:                    }
0950:
0951:                }
0952:            }
0953:
0954:            private boolean needNewLayout(Container parent) {
0955:                Dimension ops = oldParentSize;
0956:                Insets opi = oldParentInsets;
0957:                oldParentSize = parent.getSize();
0958:                oldParentInsets = parent.getInsets();
0959:                if (opi == null)
0960:                    return (true);
0961:                if (ops.equals(parent.getSize())
0962:                        && opi.equals(parent.getInsets()))
0963:                    return (false);
0964:                return (true);
0965:
0966:            }
0967:
0968:            private int resolveGenerellOffsets(int[] generellOffset,
0969:                    Dimension realSizeDim, Insets insets, int maxWidth,
0970:                    int overallHeight) {
0971:                int retval = 1;
0972:                switch (getAnchor()) {
0973:                case CENTER:
0974:                    generellOffset[0] = (realSizeDim.width - insets.left
0975:                            - insets.right - maxWidth) / 2;
0976:                    generellOffset[1] = (realSizeDim.height - insets.top
0977:                            - insets.bottom - overallHeight) / 2;
0978:                    break;
0979:                case WEST:
0980:                    generellOffset[0] = 0;
0981:                    generellOffset[1] = (realSizeDim.height - insets.top
0982:                            - insets.bottom - overallHeight) / 2;
0983:                    break;
0984:                case EAST:
0985:                    generellOffset[0] = realSizeDim.width - insets.left
0986:                            - insets.right - maxWidth;
0987:                    generellOffset[1] = (realSizeDim.height - insets.top
0988:                            - insets.bottom - overallHeight) / 2;
0989:                    break;
0990:                case NORTH:
0991:                    generellOffset[0] = (realSizeDim.width - insets.left
0992:                            - insets.right - maxWidth) / 2;
0993:                    generellOffset[1] = 0;
0994:                    break;
0995:                case SOUTH:
0996:                    generellOffset[0] = (realSizeDim.width - insets.left
0997:                            - insets.right - maxWidth) / 2;
0998:                    generellOffset[1] = realSizeDim.height - insets.top
0999:                            - insets.bottom - overallHeight;
1000:                    break;
1001:                case NORTH_WEST:
1002:                    generellOffset[0] = 0;
1003:                    generellOffset[1] = 0;
1004:                    retval = 2;
1005:                    break;
1006:                case NORTH_EAST:
1007:                    generellOffset[0] = realSizeDim.width - insets.left
1008:                            - insets.right - maxWidth;
1009:                    generellOffset[1] = 0;
1010:                    break;
1011:                case SOUTH_WEST:
1012:                    generellOffset[0] = 0;
1013:                    generellOffset[1] = realSizeDim.height - insets.top
1014:                            - insets.bottom - overallHeight;
1015:                    break;
1016:                case SOUTH_EAST:
1017:                    generellOffset[0] = realSizeDim.width - insets.left
1018:                            - insets.right - maxWidth;
1019:                    generellOffset[1] = realSizeDim.height - insets.top
1020:                            - insets.bottom - overallHeight;
1021:                    break;
1022:
1023:                }
1024:                if (generellOffset[0] < 0)
1025:                    generellOffset[0] = 0;
1026:                if (generellOffset[1] < 0)
1027:                    generellOffset[1] = 0;
1028:                return (retval);
1029:            }
1030:
1031:            /**
1032:             * Returns whether the type of component needs potential a reevaluation or not.
1033:             * 
1034:             * @param comp component to check
1035:             * @return whether the type of component needs potential a reevaluation or not
1036:             */
1037:            private boolean needsReEvaluation(Component comp) {
1038:                if ((comp instanceof  com.izforge.izpack.util.MultiLineLabel)
1039:                        || (comp instanceof  com.izforge.izpack.panels.PathSelectionPanel))
1040:                    return (true);
1041:                return (false);
1042:            }
1043:
1044:            /*
1045:             * (non-Javadoc)
1046:             * 
1047:             * @see java.awt.LayoutManager2#getLayoutAlignmentX(java.awt.Container)
1048:             */
1049:            public float getLayoutAlignmentX(Container target) {
1050:                return 0;
1051:            }
1052:
1053:            /*
1054:             * (non-Javadoc)
1055:             * 
1056:             * @see java.awt.LayoutManager2#getLayoutAlignmentY(java.awt.Container)
1057:             */
1058:            public float getLayoutAlignmentY(Container target) {
1059:                return 0;
1060:            }
1061:
1062:            /*
1063:             * (non-Javadoc)
1064:             * 
1065:             * @see java.awt.LayoutManager2#invalidateLayout(java.awt.Container)
1066:             */
1067:            public void invalidateLayout(Container target) {
1068:                // prefLayoutDim = null;
1069:            }
1070:
1071:            /*
1072:             * (non-Javadoc)
1073:             * 
1074:             * @see java.awt.LayoutManager2#maximumLayoutSize(java.awt.Container)
1075:             */
1076:            public Dimension maximumLayoutSize(Container target) {
1077:                return (minimumLayoutSize(target));
1078:            }
1079:
1080:            /*
1081:             * (non-Javadoc)
1082:             * 
1083:             * @see java.awt.LayoutManager2#addLayoutComponent(java.awt.Component, java.lang.Object)
1084:             */
1085:            public void addLayoutComponent(Component comp, Object constraints) {
1086:                if (comp == null)
1087:                    throw new NullPointerException(
1088:                            "component has to be not null");
1089:                IzPanelConstraints cc;
1090:                if (!(constraints instanceof  IzPanelConstraints)) {
1091:                    if ((comp instanceof  FillerComponent)
1092:                            && ((FillerComponent) comp).getConstraints() != null)
1093:                        cc = (IzPanelConstraints) ((FillerComponent) comp)
1094:                                .getConstraints().clone();
1095:                    else
1096:                        cc = (IzPanelConstraints) IzPanelLayout.DEFAULT_CONSTRAINTS[getIntermediarId(
1097:                                comp.getClass(), comp)].clone();
1098:                    if (NEXT_LINE.equals(constraints)) {
1099:                        cc.setXPos(0);
1100:                        cc.setYPos(NEXT_ROW);
1101:                    }
1102:                } else
1103:                    cc = (IzPanelConstraints) ((IzPanelConstraints) constraints)
1104:                            .clone();
1105:                cc.component = comp;
1106:                int i;
1107:                // Modify positions if constraint value is one of the symbolic ints.
1108:                int yPos = cc.getYPos();
1109:                if (yPos == LayoutConstants.NEXT_ROW)
1110:                    yPos = currentYPos + 1;
1111:                if (yPos == LayoutConstants.CURRENT_ROW)
1112:                    yPos = currentYPos;
1113:                cc.setYPos(yPos);
1114:                int xPos = cc.getXPos();
1115:                if (xPos == LayoutConstants.NEXT_COLUMN)
1116:                    xPos = currentXPos + 1;
1117:                if (xPos == LayoutConstants.CURRENT_COLUMN)
1118:                    xPos = currentXPos;
1119:                cc.setXPos(xPos);
1120:                // Now we know real x and y position. If needed, expand array or
1121:                // array of array.
1122:                int perfCol = cc.getXWeight() < Byte.MAX_VALUE ? cc
1123:                        .getXWeight() : 1;
1124:                if (components.size() < cc.getXPos() + perfCol) {
1125:                    for (i = components.size() - 1; i < cc.getXPos() + perfCol
1126:                            - 1; ++i)
1127:                        components.add(new ArrayList<IzPanelConstraints>());
1128:                }
1129:                IzPanelConstraints curConst = cc;
1130:                for (int j = 0; j < perfCol; ++j) {
1131:                    ArrayList<IzPanelConstraints> xComp = components.get(xPos);
1132:                    if (xComp.size() < yPos) {
1133:                        for (i = xComp.size() - 1; i < yPos - 1; ++i) {
1134:                            IzPanelConstraints dc = getDefaultConstraint(XDUMMY_CONSTRAINT);
1135:                            dc.component = new FillerComponent();
1136:                            xComp.add(dc);
1137:
1138:                        }
1139:                    }
1140:
1141:                    xComp.add(yPos, curConst);
1142:                    if (j < perfCol - 1) {
1143:                        curConst = getDefaultConstraint(XDUMMY_CONSTRAINT);
1144:                        curConst.component = new FillerComponent();
1145:                        xPos++;
1146:                    }
1147:                }
1148:                int xcsize = (components.get(xPos)).size() - 1;
1149:                if (currentYPos < xcsize)
1150:                    currentYPos = xcsize;
1151:                currentXPos = xPos;
1152:
1153:            }
1154:
1155:            /**
1156:             * Creates an invisible, component with a defined width. This component will be placed in the
1157:             * given cell of an IzPackLayout. If no constraint will be set (the default) a default
1158:             * constraint with NEXT_COLUMN and CURRENT_ROW will be used. This component has the height 0.
1159:             * The height of the row will be determined by other components in the same row.
1160:             * 
1161:             * @param width the width of the invisible component
1162:             * @return the component
1163:             */
1164:            public static Component createHorizontalStrut(int width) {
1165:                return (new FillerComponent(new Dimension(width, 0)));
1166:            }
1167:
1168:            /**
1169:             * Creates an invisible, component with a defined height. This component will be placed in the
1170:             * given cell of an IzPackLayout. If no constraint will be set (the default) a default
1171:             * constraint with column 0 and NEXT_ROW will be used. If the next component also uses NEXT_ROW,
1172:             * this strut goes over the hole width with the declared height. If more components are in the
1173:             * row, the highest of them determines the height of the row. This component has the width 0.
1174:             * The width of a row will be determined by other rows.
1175:             * 
1176:             * @param height the height of the invisible component, in pixels >= 0
1177:             * @return the component
1178:             */
1179:            public static Component createVerticalStrut(int height) {
1180:                return (new FillerComponent(new Dimension(0, height)));
1181:            }
1182:
1183:            /**
1184:             * Returns a filler component which has self the size 0|0. Additional there is a constraints
1185:             * which has the x position 0,y position NEXT_ROW, x and y weight 10, x-stretch 1.0 and the y
1186:             * gap PARAGRAPH_GAP. Add the returned component to the IzPanel. Use NEXT_LINE (or NEXT_ROW in
1187:             * the constraints) for the next added control, else the layout will be confused.
1188:             * 
1189:             * @return a filler component with the height of the defined paragraph gap
1190:             */
1191:            public static Component createParagraphGap() {
1192:                return (createGap(PARAGRAPH_GAP, VERTICAL));
1193:            }
1194:
1195:            /**
1196:             * Returns a filler component which has self the size 0|0. Additional there is a constraints
1197:             * which has the x position 0,y position NEXT_ROW, x and y weight 10, x-stretch 1.0 and the y
1198:             * gap FILLER&lt;given filler number&gt;_GAP. Add the returned component to the IzPanel. Use
1199:             * NEXT_LINE (or NEXT_ROW in the constraints) for the next added control, else the layout will
1200:             * be confused. Attention! fillerNumber determines not directly the size of filler else the
1201:             * filler type. The size can be determined in the config file as modifier in the info section
1202:             * defining from filler1YGap to filler5YGap.
1203:             * 
1204:             * @param fillerNumber number of the filler which should be used
1205:             * @return a filler component with the height of the defined paragraph gap
1206:             */
1207:            public static Component createVerticalFiller(int fillerNumber) {
1208:                // The symbolic numbers all are negative. Therefore a higher filler needs
1209:                // a less number.
1210:                return (createGap(FILLER1_GAP + 1 - fillerNumber, VERTICAL));
1211:            }
1212:
1213:            /**
1214:             * Returns a filler component which has self the size 0|0. Additional there is a constraints
1215:             * which has the position NEXT_COLUMN ,y position CURRENT_ROW, x and y weight 1, stretch 0.0 and
1216:             * the gap FILLER&lt;given filler number&gt;_GAP. Add the returned component to the IzPanel.
1217:             * Attention! fillerNumber determines not directly the size of filler else the filler type. The
1218:             * size can be determined in the config file as modifier in the info section defining from
1219:             * filler1XGap to filler5XGap.
1220:             * 
1221:             * @param fillerNumber number of the filler which should be used
1222:             * @return a filler component with the width of the defined paragraph gap
1223:             */
1224:            public static Component createHorizontalFiller(int fillerNumber) {
1225:                // The symbolic numbers all are negative. Therefore a higher filler needs
1226:                // a less number.
1227:                return (createGap(FILLER1_GAP + 1 - fillerNumber, HORIZONTAL));
1228:            }
1229:
1230:            /**
1231:             * Returns a filler component which has self the size 0|0. Additional there is a constraints
1232:             * which has the gap defined for the given gap type. If direction is HORIZONTAL, the x position
1233:             * is NEXT_COLUMN ,y position CURRENT_ROW, x and y weight 1, stretch 0.0. If direction is
1234:             * VERTICAL, the x position will by 0,y position NEXT_ROW, x and y weight 10, x-stretch 1.0. Add
1235:             * the returned component to the IzPanel. The result will be that a gap will be inserted into
1236:             * the layout at the current place with the width equal to the defined paragraph gap.
1237:             * 
1238:             * @param gapType type of gap to be used
1239:             * @param direction direction to be used
1240:             * 
1241:             * @return a filler component with the width of the defined paragraph gap
1242:             */
1243:
1244:            public static Component createGap(int gapType, int direction) {
1245:                if (direction == HORIZONTAL)
1246:                    return (new FillerComponent(new Dimension(0, 0),
1247:                            new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT,
1248:                                    DEFAULT_CONTROL_ALIGNMENT, NEXT_COLUMN,
1249:                                    CURRENT_ROW, 1, 1, gapType, 0, 0.0, 0.0)));
1250:                return (new FillerComponent(new Dimension(0, 0),
1251:                        new IzPanelConstraints(DEFAULT_CONTROL_ALIGNMENT,
1252:                                DEFAULT_CONTROL_ALIGNMENT, 0, NEXT_ROW, 10, 10,
1253:                                0, gapType, 1.0, 0.0)));
1254:            }
1255:
1256:            /**
1257:             * Returns the constraint for the given type. Valid types are declared in the interface
1258:             * <code>LayoutConstraints</code>. Possible are LABEL_CONSTRAINT, TEXT_CONSTRAINT and
1259:             * CONTROL_CONSTRAINT.
1260:             * 
1261:             * @param type for which the constraint should be returned
1262:             * @return a copy of the default constraint for the given type
1263:             */
1264:            public static IzPanelConstraints getDefaultConstraint(int type) {
1265:                return ((IzPanelConstraints) DEFAULT_CONSTRAINTS[type].clone());
1266:            }
1267:
1268:            /**
1269:             * Component which will be used as placeholder if not extern component will be set or as filler
1270:             * for struts.
1271:             * 
1272:             * @author Klaus Bartz
1273:             * 
1274:             */
1275:            public static class FillerComponent extends Component {
1276:
1277:                /**  */
1278:                private static final long serialVersionUID = 7270064864038287900L;
1279:
1280:                private Dimension size;
1281:
1282:                private IzPanelConstraints constraints;
1283:
1284:                /**
1285:                 * Default constructor creating an filler with the size 0|0.
1286:                 */
1287:                public FillerComponent() {
1288:                    this (new Dimension(0, 0));
1289:                }
1290:
1291:                /**
1292:                 * Constructor with giving the filler a size.
1293:                 * 
1294:                 * @param size dimension to be used as size for this filler.
1295:                 */
1296:                public FillerComponent(Dimension size) {
1297:                    this (size, null);
1298:                }
1299:
1300:                /**
1301:                 * Constructor with giving the filler a size and set the constraints.
1302:                 * 
1303:                 * @param size
1304:                 * @param constraints
1305:                 */
1306:                public FillerComponent(Dimension size,
1307:                        IzPanelConstraints constraints) {
1308:                    super ();
1309:                    this .size = size;
1310:                    this .constraints = constraints;
1311:                }
1312:
1313:                public Dimension getMinimumSize() {
1314:                    return (Dimension) (size.clone());
1315:                }
1316:
1317:                /*
1318:                 * (non-Javadoc)
1319:                 * 
1320:                 * @see java.awt.Component#getPreferredSize()
1321:                 */
1322:                public Dimension getPreferredSize() {
1323:                    return getMinimumSize();
1324:                }
1325:
1326:                /*
1327:                 * (non-Javadoc)
1328:                 * 
1329:                 * @see java.awt.Component#getMaximumSize()
1330:                 */
1331:                public Dimension getMaximumSize() {
1332:                    return getMinimumSize();
1333:                }
1334:
1335:                /*
1336:                 * (non-Javadoc)
1337:                 * 
1338:                 * @see java.awt.Component#getBounds()
1339:                 */
1340:                public Rectangle getBounds() {
1341:                    return (getBounds(new Rectangle()));
1342:                }
1343:
1344:                /*
1345:                 * (non-Javadoc)
1346:                 * 
1347:                 * @see java.awt.Component#getBounds(java.awt.Rectangle)
1348:                 */
1349:                public Rectangle getBounds(Rectangle rect) {
1350:                    Rectangle rv = (rect != null) ? rect : new Rectangle();
1351:                    rv.setBounds(0, 0, size.width, size.height);
1352:                    return (rv);
1353:                }
1354:
1355:                /**
1356:                 * Returns the constraints defined for this component. Often this will be null.
1357:                 * 
1358:                 * @return the constraints defined for this component
1359:                 */
1360:                public IzPanelConstraints getConstraints() {
1361:                    return constraints;
1362:                }
1363:
1364:                /**
1365:                 * Sets the constraints which should be used by this component.
1366:                 * 
1367:                 * @param constraints constraints to be used
1368:                 */
1369:                public void setConstraints(IzPanelConstraints constraints) {
1370:                    this .constraints = constraints;
1371:                }
1372:            }
1373:
1374:            /**
1375:             * Returns the anchor constant.
1376:             * 
1377:             * @return the anchor constant
1378:             */
1379:            public static int getAnchor() {
1380:                return ANCHOR;
1381:            }
1382:
1383:            /**
1384:             * Sets the anchor constant.
1385:             * 
1386:             * @param anchor symbolic constant to be used
1387:             */
1388:            public static void setAnchor(int anchor) {
1389:                ANCHOR = anchor;
1390:            }
1391:
1392:            /**
1393:             * Returns the current used type of stretching for the X-direction. Possible values are NO,
1394:             * RELATIVE and ABSOLUTE.
1395:             * 
1396:             * @return the current used type of stretching for the X-direction
1397:             */
1398:            public static int getXStretchType() {
1399:                return X_STRETCH_TYPE;
1400:            }
1401:
1402:            /**
1403:             * Sets the type of stretching to be used for the X-Direction. Possible values are NO, RELATIVE
1404:             * and ABSOLUTE.
1405:             * 
1406:             * @param x_stretch constant to be used for stretch type
1407:             */
1408:            public static void setXStretchType(int x_stretch) {
1409:                X_STRETCH_TYPE = x_stretch;
1410:            }
1411:
1412:            /**
1413:             * Returns the current used type of stretching for the Y-direction. Possible values are NO,
1414:             * RELATIVE and ABSOLUTE.
1415:             * 
1416:             * @return the current used type of stretching for the Y-direction
1417:             */
1418:            public static int getYStretchType() {
1419:                return Y_STRETCH_TYPE;
1420:            }
1421:
1422:            /**
1423:             * Sets the type of stretching to be used for the Y-Direction. Possible values are NO, RELATIVE
1424:             * and ABSOLUTE.
1425:             * 
1426:             * @param y_stretch constant to be used for stretch type
1427:             */
1428:            public static void setYStretchType(int y_stretch) {
1429:                Y_STRETCH_TYPE = y_stretch;
1430:            }
1431:
1432:            /**
1433:             * Returns the value which should be used stretching to a full line.
1434:             * 
1435:             * @return the value which should be used stretching to a full line
1436:             */
1437:            public static double getFullLineStretch() {
1438:                return FULL_LINE_STRETCH_DEFAULT;
1439:            }
1440:
1441:            /**
1442:             * Sets the value which should be used as default for stretching to a full line.
1443:             * 
1444:             * @param fullLineStretch value to be used as full line stretching default
1445:             */
1446:            public static void setFullLineStretch(double fullLineStretch) {
1447:                FULL_LINE_STRETCH_DEFAULT = fullLineStretch;
1448:
1449:            }
1450:
1451:            /**
1452:             * Returns the value which should be used stretching to a full column.
1453:             * 
1454:             * @return the value which should be used stretching to a full column
1455:             */
1456:            public static double getFullColumnStretch() {
1457:                return FULL_COLUMN_STRETCH_DEFAULT;
1458:            }
1459:
1460:            /**
1461:             * Sets the value which should be used as default for stretching to a full column.
1462:             * 
1463:             * @param fullStretch value to be used as full column stretching default
1464:             */
1465:            public static void setFullColumnStretch(double fullStretch) {
1466:                FULL_COLUMN_STRETCH_DEFAULT = fullStretch;
1467:
1468:            }
1469:
1470:            /**
1471:             * Verifies whether a gap id is valid or not. If the id is less than zero, the sign will be
1472:             * removed. If the id is out of range, an IndexOutOfBoundsException will be thrown. The return
1473:             * value is the verified unsigned id.
1474:             * 
1475:             * @param gapId to be verified
1476:             * @return the verified gap id
1477:             */
1478:            public static int verifyGapId(int gapId) {
1479:                if (gapId < 0)
1480:                    gapId = -gapId;
1481:                if (gapId >= DEFAULT_X_GAPS.length)
1482:                    throw new IndexOutOfBoundsException(
1483:                            "gapId is not in the default gap container.");
1484:                return (gapId);
1485:            }
1486:
1487:            /**
1488:             * Returns the default x gap for the given gap id.
1489:             * 
1490:             * @param gapId for which the default x gap should be returned
1491:             * @return the default x gap for the given gap id
1492:             */
1493:            public static int getDefaultXGap(int gapId) {
1494:                gapId = verifyGapId(gapId);
1495:                return DEFAULT_X_GAPS[gapId];
1496:            }
1497:
1498:            /**
1499:             * Set the gap for the given gap id for the x default gaps.
1500:             * 
1501:             * @param gap to be used as default
1502:             * @param gapId for which the default should be set
1503:             */
1504:            public static void setDefaultXGap(int gap, int gapId) {
1505:                gapId = verifyGapId(gapId);
1506:                DEFAULT_X_GAPS[gapId] = gap;
1507:            }
1508:
1509:            /**
1510:             * Returns the default y gap for the given gap id.
1511:             * 
1512:             * @param gapId for which the default y gap should be returned
1513:             * @return the default x gap for the given gap id
1514:             */
1515:            public static int getDefaultYGap(int gapId) {
1516:                gapId = verifyGapId(gapId);
1517:                return DEFAULT_Y_GAPS[gapId];
1518:            }
1519:
1520:            /**
1521:             * Set the gap for the given gap id for the y default gaps.
1522:             * 
1523:             * @param gap to be used as default
1524:             * @param gapId for which the default should be set
1525:             */
1526:            public static void setDefaultYGap(int gap, int gapId) {
1527:                gapId = verifyGapId(gapId);
1528:                DEFAULT_Y_GAPS[gapId] = gap;
1529:            }
1530:
1531:            /**
1532:             * Returns the default length used by textfields.
1533:             * 
1534:             * @return the default length used by textfields
1535:             */
1536:            public static int getDefaultTextfieldLength() {
1537:                return DEFAULT_TEXTFIELD_LENGTH;
1538:            }
1539:
1540:            /**
1541:             * Sets the value for the default length of textfields.
1542:             * 
1543:             * @param val to be set as default length for textfields
1544:             */
1545:            public static void setDefaultTextfieldLength(int val) {
1546:                DEFAULT_TEXTFIELD_LENGTH = val;
1547:            }
1548:
1549:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.