Source Code Cross Referenced for LayoutInterval.java in  » IDE-Netbeans » form » org » netbeans » modules » form » layoutdesign » 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 » IDE Netbeans » form » org.netbeans.modules.form.layoutdesign 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.modules.form.layoutdesign;
0043:
0044:        import java.util.ArrayList;
0045:        import java.util.Collections;
0046:        import java.util.Iterator;
0047:        import java.util.LinkedList;
0048:        import java.util.List;
0049:
0050:        /**
0051:         * @author Tomas Pavek
0052:         */
0053:
0054:        public final class LayoutInterval implements  LayoutConstants {
0055:            static final int ATTRIBUTE_FILL = 1;
0056:            static final int ATTRIBUTE_FORMER_FILL = 2;
0057:            static final int ATTR_CLOSED_GROUP = 32;
0058:
0059:            // attributes denoting intervals with different size behavior in design time
0060:            static final int ATTR_DESIGN_CONTAINER_GAP = 4;
0061:            static final int ATTR_DESIGN_RESIZING = 8;
0062:            static final int ATTR_DESIGN_SUPPRESSED_RESIZING = 16;
0063:
0064:            // attributes used during aligning
0065:            static final int ATTR_ALIGN_PRE = 64;
0066:            static final int ATTR_ALIGN_POST = 128;
0067:
0068:            static final int DESIGN_ATTRS = ATTR_DESIGN_CONTAINER_GAP
0069:                    | ATTR_DESIGN_RESIZING | ATTR_DESIGN_SUPPRESSED_RESIZING
0070:                    | ATTR_ALIGN_PRE | ATTR_ALIGN_POST;
0071:
0072:            static final int ATTR_PERSISTENT_MASK = ATTRIBUTE_FILL
0073:                    | ATTRIBUTE_FORMER_FILL | ATTR_CLOSED_GROUP;
0074:
0075:            // type of the interval - SINGLE, SEQUENTIAL, PARALLEL
0076:            private int type;
0077:
0078:            // additional attributes set on the interval as bit flags
0079:            private int attributes;
0080:
0081:            // alignment of the interval (if in a parallel group)
0082:            private int alignment = DEFAULT;
0083:
0084:            // parent interval (group )
0085:            private LayoutInterval parentInterval;
0086:
0087:            // internall alignment of a group (if this is a parallel group)
0088:            private int groupAlignment = LEADING;
0089:
0090:            // contained sub-intervals (if this is a group)
0091:            private List<LayoutInterval> subIntervals;
0092:
0093:            // associated LayoutComponent (if any)
0094:            private LayoutComponent layoutComponent;
0095:
0096:            // type of padding (default gap; if this is a preferred gap)
0097:            private PaddingType paddingType;
0098:            private String[] paddingDefComps; // 2 components, needed for INDENT gap
0099:
0100:            // minimum, preferred, and maximum size definitions
0101:            private int minSize;
0102:            private int prefSize;
0103:            private int maxSize;
0104:
0105:            // current position and size of the interval in the visual representation
0106:            private LayoutRegion currentSpace;
0107:
0108:            // -----
0109:            // setup methods - each setter should be called max. once after creation,
0110:            // other changes should be done via LayoutModel to be fired and recorded
0111:            // for undo/redo
0112:
0113:            LayoutInterval(int type) {
0114:                this .type = type;
0115:                minSize = NOT_EXPLICITLY_DEFINED;
0116:                prefSize = NOT_EXPLICITLY_DEFINED;
0117:                if (type == SEQUENTIAL || type == PARALLEL) {
0118:                    subIntervals = new ArrayList<LayoutInterval>();
0119:                    maxSize = NOT_EXPLICITLY_DEFINED; // group can resize by default
0120:                } else {
0121:                    assert type == SINGLE;
0122:                    maxSize = USE_PREFERRED_SIZE;
0123:                }
0124:            }
0125:
0126:            void setAlignment(int alignment) {
0127:                this .alignment = alignment;
0128:            }
0129:
0130:            void setGroupAlignment(int alignment) {
0131:                assert alignment != DEFAULT && type == PARALLEL;
0132:                groupAlignment = alignment;
0133:            }
0134:
0135:            void setComponent(LayoutComponent comp) {
0136:                this .layoutComponent = comp;
0137:            }
0138:
0139:            void setMinimumSize(int size) {
0140:                // for groups we expect only two states - shrinking suppressed/allowed
0141:                assert isSingle()
0142:                        || (size == USE_PREFERRED_SIZE || size == NOT_EXPLICITLY_DEFINED);
0143:                minSize = size;
0144:            }
0145:
0146:            void setPreferredSize(int size) {
0147:                assert (size != USE_PREFERRED_SIZE && isSingle())
0148:                        || (size == NOT_EXPLICITLY_DEFINED); // groups should not have explicit size
0149:                prefSize = size;
0150:            }
0151:
0152:            void setMaximumSize(int size) {
0153:                // for single interval the max size must be defined
0154:                // for groups only two states - growing suppressed or allowed
0155:                assert (isSingle() && size != NOT_EXPLICITLY_DEFINED)
0156:                        || (isGroup() && (size == USE_PREFERRED_SIZE || size == NOT_EXPLICITLY_DEFINED));
0157:                maxSize = size;
0158:            }
0159:
0160:            void setSize(int size) {
0161:                setMinimumSize(size);
0162:                setPreferredSize(size);
0163:                setMaximumSize(size);
0164:            }
0165:
0166:            void setSizes(int min, int pref, int max) {
0167:                setMinimumSize(min);
0168:                setPreferredSize(pref);
0169:                setMaximumSize(max);
0170:            }
0171:
0172:            int getMinimumSize() {
0173:                return minSize;
0174:            }
0175:
0176:            int getPreferredSize() {
0177:                return prefSize;
0178:            }
0179:
0180:            int getMaximumSize() {
0181:                return maxSize;
0182:            }
0183:
0184:            void setPaddingType(PaddingType type) {
0185:                paddingType = type;
0186:            }
0187:
0188:            String[] getPaddingDefComponents() {
0189:                return paddingDefComps;
0190:            }
0191:
0192:            void setPaddingDefComponents(String compId1, String compId2) {
0193:                if (compId1 == null) {
0194:                    paddingDefComps = null;
0195:                } else {
0196:                    paddingDefComps = new String[] { compId1, compId2 };
0197:                }
0198:            }
0199:
0200:            // ---------
0201:            // public methods
0202:
0203:            /**
0204:             * Returns the type of the structure of the interval. It can be a single
0205:             * interval or a group with sub-intervals arranged either sequentially
0206:             * or parallelly.
0207:             * @return type of the interval: SINGLE, SEQUENTIAL, or PARALLEL
0208:             */
0209:            public int getType() {
0210:                return type;
0211:            }
0212:
0213:            /**
0214:             * Returns alignment of the interval within a parallel group. If the
0215:             * interval is not part of a parallel group, the alignment is meaningless.
0216:             * @return alignment of the interval within a parallel group (LEADING,
0217:             *         TRAILING, CENTER, or BASELINE); DEFAULT if in a sequential group
0218:             */
0219:            public int getAlignment() {
0220:                return alignment == DEFAULT && parentInterval != null
0221:                        && parentInterval.isParallel() ? parentInterval
0222:                        .getGroupAlignment() : alignment;
0223:            }
0224:
0225:            /**
0226:             * Returns the common alignment of sub-intervals within a group (makes
0227:             * sense only for a parallel group).
0228:             * @return alignment of the group (LEADING, TRAILING, CENTER, or BASELINE)
0229:             */
0230:            public int getGroupAlignment() {
0231:                return groupAlignment;
0232:            }
0233:
0234:            /**
0235:             * Returns the minimum size of the interval. Instead of a specific size
0236:             * it may return also one of the constants NOT_EXPLICITLY_DEFINED or
0237:             * USE_PREFERRED_SIZE.
0238:             * @param designTime if true, size for design time layout is returned
0239:             *        (design time behavior may be different in terms of resizing)
0240:             * @return minimum interval size, or one of the constants:
0241:             *         NOT_EXPLICITLY_DEFINED or USE_PREFERRED_SIZE
0242:             */
0243:            public int getMinimumSize(boolean designTime) {
0244:                if (!designTime) {
0245:                    return minSize;
0246:                }
0247:                if (hasAttribute(ATTR_DESIGN_SUPPRESSED_RESIZING)) {
0248:                    assert !hasAttribute(ATTR_DESIGN_RESIZING);
0249:                    return USE_PREFERRED_SIZE;
0250:                }
0251:                if (hasAttribute(ATTR_DESIGN_RESIZING)) {
0252:                    return isEmptySpace()
0253:                            && (getPreferredSize(designTime) != 0) ? NOT_EXPLICITLY_DEFINED
0254:                            : 0;
0255:                }
0256:                return minSize;
0257:            }
0258:
0259:            /**
0260:             * Returns the preferred size of the interval. If no specific size was set,
0261:             * it returns NOT_EXPLICITLY_DEFINED constant.
0262:             * @param designTime if true, size for design time layout is returned
0263:             *        (design time behavior may be different in terms of resizing)
0264:             * @return preferred size of the interval, or NOT_EXPLICITLY_DEFINED constant
0265:             */
0266:            public int getPreferredSize(boolean designTime) {
0267:                return prefSize;
0268:            }
0269:
0270:            /**
0271:             * Returns the maximum size of the interval. Instead of a specific size
0272:             * it may return also one of the constants NOT_EXPLICITLY_DEFINED or
0273:             * USE_PREFERRED_SIZE.
0274:             * @param designTime if true, size for design time layout is returned
0275:             *        (design time behavior may be different in terms of resizing)
0276:             * @return maximum interval size, or one of the constants:
0277:             *         NOT_EXPLICITLY_DEFINED or USE_PREFERRED_SIZE
0278:             */
0279:            public int getMaximumSize(boolean designTime) {
0280:                if (!designTime) {
0281:                    return maxSize;
0282:                }
0283:                if (hasAttribute(ATTR_DESIGN_SUPPRESSED_RESIZING)) {
0284:                    assert !hasAttribute(ATTR_DESIGN_RESIZING);
0285:                    return USE_PREFERRED_SIZE;
0286:                }
0287:                if (hasAttribute(ATTR_DESIGN_RESIZING)) {
0288:                    return Short.MAX_VALUE;
0289:                }
0290:                return maxSize;
0291:            }
0292:
0293:            /**
0294:             * Returns number of sub-intervals of this interval.
0295:             * @return number of sub-intervals of this interval, 0 if it is not a group
0296:             */
0297:            public int getSubIntervalCount() {
0298:                return subIntervals != null ? subIntervals.size() : 0;
0299:            }
0300:
0301:            /**
0302:             * Returns an iterator of sub-intervals.
0303:             * @return iterator of sub-intervals, empty if there are no sub-intervals
0304:             */
0305:            public Iterator<LayoutInterval> getSubIntervals() {
0306:                return subIntervals != null ? subIntervals.iterator()
0307:                        : Collections.EMPTY_LIST.iterator();
0308:            }
0309:
0310:            /**
0311:             * If this interval represents a component's width or height, this methods
0312:             * returns the component.
0313:             * @return LayoutComponent instance representing the associated component.
0314:             *         Null if this interval does not represent a component.
0315:             */
0316:            public LayoutComponent getComponent() {
0317:                return layoutComponent;
0318:            }
0319:
0320:            // helper methods (redundant - based on derived information)
0321:
0322:            public boolean isParallel() {
0323:                return type == PARALLEL;
0324:            }
0325:
0326:            public boolean isSequential() {
0327:                return type == SEQUENTIAL;
0328:            }
0329:
0330:            /**
0331:             * Returns whether this interval defines a lyout component.
0332:             * @return true if this interval represents a layout component,
0333:             *         false otherwise
0334:             */
0335:            public boolean isComponent() {
0336:                return layoutComponent != null;
0337:            }
0338:
0339:            /**
0340:             * Returns whether this interval defines an "empty" space (gap) in the
0341:             * layout, not including nor being able to include any component.
0342:             * @return true if this is a single interval not representing a component,
0343:             *         false otherwise
0344:             */
0345:            public boolean isEmptySpace() {
0346:                return type == SINGLE && layoutComponent == null;
0347:            }
0348:
0349:            public boolean isDefaultPadding(boolean designTime) {
0350:                return isEmptySpace()
0351:                        && (getMinimumSize(designTime) == NOT_EXPLICITLY_DEFINED || getPreferredSize(designTime) == NOT_EXPLICITLY_DEFINED);
0352:            }
0353:
0354:            public PaddingType getPaddingType() {
0355:                return paddingType;
0356:            }
0357:
0358:            public boolean isSingle() {
0359:                return type == SINGLE;
0360:            }
0361:
0362:            /**
0363:             * Returns whether this interval represents a group structure that can have
0364:             * have sub-intervals.
0365:             * @return whether this interval is a group, either sequential or parallel
0366:             */
0367:            public boolean isGroup() {
0368:                return type == SEQUENTIAL || type == PARALLEL;
0369:            }
0370:
0371:            /**
0372:             * @return whether the interval is allowed to grow (according to its
0373:             *         definition); if allowed, the real growing possibility may still
0374:             *         depend on the associated component
0375:             */
0376:            //    public boolean isAllowedToGrow() {
0377:            //        return maxSize != USE_PREFERRED_SIZE
0378:            //               && (prefSize == NOT_EXPLICITLY_DEFINED
0379:            //                   || maxSize == NOT_EXPLICITLY_DEFINED
0380:            //                   || maxSize > prefSize);
0381:            //    }
0382:            /**
0383:             * @return whether the interval is allowed to shrink (according to its
0384:             *         definition); if allowed, the real growing possibility may still
0385:             *         depend on the associated component
0386:             */
0387:            //    public boolean isAllowedToShrink() {
0388:            //        return minSize != USE_PREFERRED_SIZE
0389:            //               && (prefSize == NOT_EXPLICITLY_DEFINED
0390:            //                   || minSize == NOT_EXPLICITLY_DEFINED
0391:            //                   || minSize < prefSize);
0392:            //    }
0393:            // end of public methods
0394:            // -----
0395:            boolean hasAttribute(int attr) {
0396:                return (attributes & attr) == attr;
0397:            }
0398:
0399:            void setAttribute(int attr) {
0400:                attributes |= attr;
0401:            }
0402:
0403:            void unsetAttribute(int attr) {
0404:                attributes &= ~attr;
0405:            }
0406:
0407:            /**
0408:             * Sets attributes of the layout interval. Should be used by persistence manager only!
0409:             *
0410:             * @param attrs attributes.
0411:             */
0412:            void setAttributes(int attrs) {
0413:                attributes = attrs;
0414:            }
0415:
0416:            /**
0417:             * Returns attributes of this layout interval. You should use
0418:             * <code>hasAttribute()</code> when you are interested in one
0419:             * particular attribute.
0420:             */
0421:            int getAttributes() {
0422:                return attributes;
0423:            }
0424:
0425:            /**
0426:             * @return the value of the alignment field of the interval - unlike
0427:             *         getAlignment() it does not ask the parent if not set (DEFAULT)
0428:             */
0429:            int getRawAlignment() {
0430:                return alignment;
0431:            }
0432:
0433:            // -----
0434:
0435:            public LayoutInterval getParent() {
0436:                return parentInterval;
0437:            }
0438:
0439:            int add(LayoutInterval interval, int index) {
0440:                if (index < 0) {
0441:                    index = subIntervals.size();
0442:                }
0443:                subIntervals.add(index, interval);
0444:                interval.parentInterval = this ;
0445:                return index;
0446:            }
0447:
0448:            int remove(LayoutInterval interval) {
0449:                int index = subIntervals.indexOf(interval);
0450:                if (index >= 0) {
0451:                    subIntervals.remove(index);
0452:                    interval.parentInterval = null;
0453:                }
0454:                return index;
0455:            }
0456:
0457:            LayoutInterval remove(int index) {
0458:                LayoutInterval interval = subIntervals.get(index);
0459:                subIntervals.remove(index);
0460:                interval.parentInterval = null;
0461:                return interval;
0462:            }
0463:
0464:            LayoutInterval getSubInterval(int index) {
0465:                return subIntervals != null ? subIntervals.get(index) : null;
0466:            }
0467:
0468:            int indexOf(LayoutInterval interval) {
0469:                return subIntervals != null ? subIntervals.indexOf(interval)
0470:                        : -1;
0471:            }
0472:
0473:            boolean isParentOf(LayoutInterval interval) {
0474:                if (isGroup()) {
0475:                    do {
0476:                        interval = interval.getParent();
0477:                        if (interval == this )
0478:                            return true;
0479:                    } while (interval != null);
0480:                }
0481:                return false;
0482:            }
0483:
0484:            // -----
0485:            // current state of the layout - current position and size of layout
0486:            // interval kept to be available quickly for the layout designer
0487:
0488:            LayoutRegion getCurrentSpace() {
0489:                assert !isEmptySpace(); // [temporary - nobody should be interested in gap positions]
0490:                if (currentSpace == null) {
0491:                    currentSpace = new LayoutRegion();
0492:                }
0493:                return currentSpace;
0494:            }
0495:
0496:            void setCurrentSpace(LayoutRegion space) {
0497:                currentSpace = space;
0498:            }
0499:
0500:            // -----
0501:            // static helper methods
0502:
0503:            /**
0504:             * @return the closest parent interval that matches given type
0505:             */
0506:            static LayoutInterval getFirstParent(LayoutInterval interval,
0507:                    int type) {
0508:                LayoutInterval parent = interval.getParent();
0509:                while (parent != null && parent.getType() != type) {
0510:                    parent = parent.getParent();
0511:                }
0512:                return parent;
0513:            }
0514:
0515:            static LayoutInterval getRoot(LayoutInterval interval) {
0516:                while (interval.getParent() != null) {
0517:                    interval = interval.getParent();
0518:                }
0519:                //        assert interval.isParallel();
0520:                return interval;
0521:            }
0522:
0523:            /**
0524:             * Finds common parent of the given intervals.
0525:             *
0526:             * @param intervals intervals whose parent should be found.
0527:             * @return common parent of the given intervals.
0528:             */
0529:            static LayoutInterval getCommonParent(LayoutInterval[] intervals) {
0530:                assert (intervals != null) && (intervals.length > 0);
0531:                LayoutInterval parent = intervals[0].getParent();
0532:                for (int i = 1; i < intervals.length; i++) {
0533:                    parent = getCommonParent(parent, intervals[i]);
0534:                }
0535:                return parent;
0536:            }
0537:
0538:            /**
0539:             * Finds common parent of two given intervals. In case one interval is
0540:             * parent of the other then this interval is returned directly, not its
0541:             * parent.
0542:             *
0543:             * @param interval1 interval whose parent should be found.
0544:             * @param interval2 interval whose parent should be found.
0545:             * @return common parent of two given intervals.
0546:             */
0547:            static LayoutInterval getCommonParent(LayoutInterval interval1,
0548:                    LayoutInterval interval2) {
0549:                // Find all parents of given intervals
0550:                Iterator parents1 = parentsOfInterval(interval1).iterator();
0551:                Iterator parents2 = parentsOfInterval(interval2).iterator();
0552:                LayoutInterval parent1 = (LayoutInterval) parents1.next();
0553:                LayoutInterval parent2 = (LayoutInterval) parents2.next();
0554:                assert (parent1 == parent2);
0555:
0556:                // Candidate for the common parent
0557:                LayoutInterval parent = null;
0558:                while (parent1 == parent2) {
0559:                    parent = parent1;
0560:                    if (parents1.hasNext()) {
0561:                        parent1 = (LayoutInterval) parents1.next();
0562:                    } else {
0563:                        break;
0564:                    }
0565:                    if (parents2.hasNext()) {
0566:                        parent2 = (LayoutInterval) parents2.next();
0567:                    } else {
0568:                        break;
0569:                    }
0570:                }
0571:                return parent;
0572:            }
0573:
0574:            /**
0575:             * Calculates all parents of the given interval.
0576:             *
0577:             * @param interval interval whose parents should be found.
0578:             * @return <code>List</code> of <code>LayoutInterval</code> objects that
0579:             * are parents of the given interval. The root is the first in the list;
0580:             * the interval itelf is also included - at the end.
0581:             */
0582:            private static List<LayoutInterval> parentsOfInterval(
0583:                    LayoutInterval interval) {
0584:                List<LayoutInterval> parents = new LinkedList<LayoutInterval>();
0585:                while (interval != null) {
0586:                    parents.add(0, interval);
0587:                    interval = interval.getParent();
0588:                }
0589:                return parents;
0590:            }
0591:
0592:            static int getCount(LayoutInterval group, int alignment,
0593:                    boolean nonEmpty) {
0594:                int n = 0;
0595:                Iterator it = group.getSubIntervals();
0596:                while (it.hasNext()) {
0597:                    LayoutInterval li = (LayoutInterval) it.next();
0598:                    if ((group.isSequential()
0599:                            || alignment == LayoutRegion.ALL_POINTS
0600:                            || li.getAlignment() == alignment || wantResize(li))
0601:                            && (!nonEmpty || !li.isEmptySpace())) { // count in
0602:                        n++;
0603:                    }
0604:                }
0605:                return n;
0606:            }
0607:
0608:            static LayoutInterval getDirectNeighbor(LayoutInterval interval,
0609:                    int alignment, boolean nonEmpty) {
0610:                LayoutInterval parent = interval.getParent();
0611:                if (parent == null || parent.isParallel())
0612:                    return null;
0613:
0614:                LayoutInterval neighbor = null;
0615:                int d = (alignment == LEADING ? -1 : 1);
0616:                int n = parent.getSubIntervalCount();
0617:                int index = parent.indexOf(interval) + d;
0618:                while (index >= 0 && index < n && neighbor == null) {
0619:                    LayoutInterval li = parent.getSubInterval(index);
0620:                    index += d;
0621:                    if (!nonEmpty || !li.isEmptySpace()) {
0622:                        neighbor = li;
0623:                    }
0624:                }
0625:                return neighbor;
0626:            }
0627:
0628:            /**
0629:             * @param alignment direction in which the neighbor is looked for (LEADING or TRAILING)
0630:             * @param nonEmpty true if empty spaces (gaps) should be skipped
0631:             * @param outOfParent true if can go up (out of the first sequential parent)
0632:             *                         for an indirect neighbor
0633:             * @param aligned true if the indirect neighbor must be in contact with the
0634:             *                     given interval
0635:             */
0636:            static LayoutInterval getNeighbor(LayoutInterval interval,
0637:                    int alignment, boolean nonEmpty, boolean outOfParent,
0638:                    boolean aligned) {
0639:                assert alignment == LEADING || alignment == TRAILING;
0640:
0641:                LayoutInterval neighbor = null;
0642:                LayoutInterval parent = interval;
0643:                int d = (alignment == LEADING ? -1 : 1);
0644:
0645:                do {
0646:                    do { // find sequential parent first
0647:                        interval = parent;
0648:                        parent = interval.getParent();
0649:                        if (aligned && parent != null && parent.isParallel()
0650:                                && !isAlignedAtBorder(interval, alignment)) { // interval not aligned in parent
0651:                            parent = null;
0652:                        }
0653:                    } while (parent != null && parent.isParallel());
0654:
0655:                    if (parent != null) { // look for the neighbor in the sequence
0656:                        neighbor = getDirectNeighbor(interval, alignment,
0657:                                nonEmpty);
0658:                    }
0659:                } while (neighbor == null && parent != null && outOfParent);
0660:
0661:                return neighbor;
0662:            }
0663:
0664:            static LayoutInterval getNeighbor(LayoutInterval interval,
0665:                    int parentType, int alignment) {
0666:                assert alignment == LEADING || alignment == TRAILING;
0667:                LayoutInterval sibling = null;
0668:                LayoutInterval parent = interval;
0669:                do {
0670:                    do {
0671:                        interval = parent;
0672:                        parent = parent.getParent();
0673:                    } while ((parent != null)
0674:                            && (parent.getType() != parentType));
0675:                    if (parent != null) {
0676:                        List subs = parent.subIntervals;
0677:                        int index = subs.indexOf(interval);
0678:                        if ((alignment == LEADING) && (index > 0)) {
0679:                            sibling = (LayoutInterval) subs.get(index - 1);
0680:                        } else if ((alignment == TRAILING)
0681:                                && (index + 1 < subs.size())) {
0682:                            sibling = (LayoutInterval) subs.get(index + 1);
0683:                        }
0684:                    }
0685:                } while ((parent != null) && (sibling == null));
0686:                return sibling;
0687:            }
0688:
0689:            static boolean startsWithEmptySpace(LayoutInterval interval,
0690:                    int alignment) {
0691:                assert alignment == LEADING || alignment == TRAILING;
0692:                if (interval.isSingle()) {
0693:                    return interval.isEmptySpace();
0694:                }
0695:                if (interval.isSequential()) {
0696:                    int index = alignment == LEADING ? 0 : interval
0697:                            .getSubIntervalCount() - 1;
0698:                    return startsWithEmptySpace(interval.getSubInterval(index),
0699:                            alignment);
0700:                } else { // parallel group
0701:                    for (Iterator it = interval.getSubIntervals(); it.hasNext();) {
0702:                        LayoutInterval li = (LayoutInterval) it.next();
0703:                        if (startsWithEmptySpace(li, alignment)) {
0704:                            return true;
0705:                        }
0706:                    }
0707:                }
0708:                return false;
0709:            }
0710:
0711:            /**
0712:             * Checks whether an interval is permanently aligned to its parent at given
0713:             * border. (The asked relation is hard, always maintained by the layout.)
0714:             * For a sequential parent the interval is aligned if it is first or last.
0715:             * For parallel parent the interval must have the given alignment in the
0716:             * group, or be resizing.
0717:             */
0718:            static boolean isAlignedAtBorder(LayoutInterval interval,
0719:                    int alignment) {
0720:                if (alignment != LEADING && alignment != TRAILING) {
0721:                    return false;
0722:                }
0723:                LayoutInterval parent = interval.getParent();
0724:                if (parent == null) {
0725:                    return false;
0726:                }
0727:                if (parent.isSequential()) {
0728:                    int index = alignment == LEADING ? 0 : parent
0729:                            .getSubIntervalCount() - 1;
0730:                    return interval == parent.getSubInterval(index);
0731:                } else { // parallel parent
0732:                    return interval.getAlignment() == alignment
0733:                            || wantResize(interval);
0734:                }
0735:            }
0736:
0737:            /**
0738:             * Checks whether an interval is permanently aligned with a given parent
0739:             * interval - need not be the direct parent. This is a multi-level version
0740:             * of the other (simple) isAlignedAtBorder method.
0741:             */
0742:            static boolean isAlignedAtBorder(LayoutInterval interval,
0743:                    LayoutInterval parent, int alignment) {
0744:                do {
0745:                    if (!isAlignedAtBorder(interval, alignment)) {
0746:                        return false;
0747:                    }
0748:                    interval = interval.getParent();
0749:                } while (interval != parent);
0750:                return true;
0751:            }
0752:
0753:            /**
0754:             * Checks whether given interval is placed at border side of its parent.
0755:             * Cares about the current visual situation only - the place may change if
0756:             * the alignment is not backed by the layout structure.
0757:             * Note this method requires the current visual state (positions) of the
0758:             * relevant intervals to be up-to-date.
0759:             */
0760:            static boolean isPlacedAtBorder(LayoutInterval interval,
0761:                    int dimension, int alignment) {
0762:                if (alignment != LEADING && alignment != TRAILING) {
0763:                    return false;
0764:                }
0765:                LayoutInterval parent = interval.getParent();
0766:                if (parent == null) {
0767:                    return false;
0768:                }
0769:                if (interval.isEmptySpace()) {
0770:                    if (parent.isSequential()) {
0771:                        int index = alignment == LEADING ? 0 : parent
0772:                                .getSubIntervalCount() - 1;
0773:                        return interval == parent.getSubInterval(index);
0774:                    } else { // gap in parallel parent
0775:                        return true;
0776:                    }
0777:                } else { // check visual position
0778:                    return LayoutRegion.distance(interval.getCurrentSpace(),
0779:                            parent.getCurrentSpace(), dimension, alignment,
0780:                            alignment) == 0;
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Checks whether an interval is placed at border side of given parent
0786:             * (need not be the direct parent). This is a multi-level version of the
0787:             * simpler isPlacededAtBorder method.
0788:             * Note this method requires the current visual state (positions) of the
0789:             * relevant intervals to be up-to-date.
0790:             */
0791:            static boolean isPlacedAtBorder(LayoutInterval interval,
0792:                    LayoutInterval parent, int dimension, int alignment) {
0793:                if (alignment != LEADING && alignment != TRAILING) {
0794:                    return false;
0795:                }
0796:                if (interval.isEmptySpace()) {
0797:                    LayoutInterval p = interval.getParent();
0798:                    if (p.isSequential()) {
0799:                        int index = alignment == LEADING ? 0 : p
0800:                                .getSubIntervalCount() - 1;
0801:                        if (interval != p.getSubInterval(index)) {
0802:                            return false;
0803:                        }
0804:                    }
0805:                    if (p == parent) {
0806:                        return true;
0807:                    }
0808:                    interval = p;
0809:                }
0810:                return LayoutRegion.distance(interval.getCurrentSpace(), parent
0811:                        .getCurrentSpace(), dimension, alignment, alignment) == 0
0812:                        && parent.isParentOf(interval);
0813:            }
0814:
0815:            // [to be replaced by separate methods like isAlignedAtBorder, isPlacedBorder, isLastInterval]
0816:            static boolean isBorderInterval(LayoutInterval interval,
0817:                    int alignment, boolean attached) {
0818:                LayoutInterval parent = interval.getParent();
0819:                if (parent != null
0820:                        && (alignment == LEADING || alignment == TRAILING)) {
0821:                    if (parent.isSequential()) {
0822:                        int index = alignment == LEADING ? 0 : parent
0823:                                .getSubIntervalCount() - 1;
0824:                        while (index >= 0
0825:                                && index < parent.getSubIntervalCount()) {
0826:                            LayoutInterval li = parent.getSubInterval(index);
0827:                            if (li == interval) {
0828:                                return true;
0829:                            } else if (attached || !li.isEmptySpace()) {
0830:                                return false;
0831:                            }
0832:                            index += alignment == LEADING ? 1 : -1;
0833:                        }
0834:                    } else {
0835:                        return !attached
0836:                                || interval.getAlignment() == alignment
0837:                                || wantResize(interval);
0838:                    }
0839:                    //                if (interval.getAlignment() == alignment) {
0840:                    //                return interval.getCurrentSpace().positions[dimension][alignment]
0841:                    //                       == parent.getCurrentSpace().positions[dimension][alignment];
0842:                }
0843:                return false;
0844:            }
0845:
0846:            static boolean isClosedGroup(LayoutInterval group, int alignment) {
0847:                assert group.isParallel();
0848:
0849:                if (group.hasAttribute(ATTR_CLOSED_GROUP)
0850:                        || group.getGroupAlignment() == CENTER
0851:                        || group.getGroupAlignment() == BASELINE) {
0852:                    return true;
0853:                }
0854:
0855:                Iterator it = group.getSubIntervals();
0856:                while (it.hasNext()) {
0857:                    LayoutInterval li = (LayoutInterval) it.next();
0858:                    if (li.getAlignment() == alignment || wantResize(li)) {
0859:                        return true;
0860:                    }
0861:                }
0862:                return false;
0863:            }
0864:
0865:            static boolean isExplicitlyClosedGroup(LayoutInterval group) {
0866:                return group.hasAttribute(ATTR_CLOSED_GROUP);
0867:            }
0868:
0869:            static boolean isDefaultPadding(LayoutInterval interval) {
0870:                return interval.isEmptySpace()
0871:                        && (interval.getMinimumSize() == NOT_EXPLICITLY_DEFINED || interval
0872:                                .getPreferredSize() == NOT_EXPLICITLY_DEFINED);
0873:            }
0874:
0875:            static boolean isFixedDefaultPadding(LayoutInterval interval) {
0876:                return interval.isEmptySpace()
0877:                        && (interval.getMinimumSize() == NOT_EXPLICITLY_DEFINED || interval
0878:                                .getMinimumSize() == USE_PREFERRED_SIZE)
0879:                        && interval.getPreferredSize() == NOT_EXPLICITLY_DEFINED
0880:                        && (interval.getMaximumSize() == NOT_EXPLICITLY_DEFINED || interval
0881:                                .getMaximumSize() == USE_PREFERRED_SIZE);
0882:            }
0883:
0884:            /**
0885:             * @return whether given interval is allowed to resize (not defined as fixed)
0886:             */
0887:            static boolean canResize(LayoutInterval interval) {
0888:                // [don't care about shrinking, assuming min possibly not defined - is it ok?]
0889:                int max = interval.getMaximumSize();
0890:                int pref = interval.getPreferredSize();
0891:                assert interval.isGroup() || max != NOT_EXPLICITLY_DEFINED;
0892:                return (max != pref && max != USE_PREFERRED_SIZE)
0893:                        || max == NOT_EXPLICITLY_DEFINED;
0894:            }
0895:
0896:            /**
0897:             * Finds out whether given interval would resize if allowed (given more
0898:             * space by its parent).
0899:             * @return whether given interval would resize if given opportunity
0900:             */
0901:            static boolean wantResize(LayoutInterval interval) {
0902:                return canResize(interval)
0903:                        && (!interval.isGroup() || contentWantResize(interval));
0904:            }
0905:
0906:            /**
0907:             * Finds out whether given interval would resize if allowed (given more
0908:             * space by its parent). This method also considers resizing of the whole
0909:             * layout (some parent of the interval could block the resizing).
0910:             * @return whether given interval would resize if given opportunity
0911:             */
0912:            static boolean wantResizeInLayout(LayoutInterval interval) {
0913:                if (!wantResize(interval))
0914:                    return false;
0915:
0916:                while (interval.getParent() != null) {
0917:                    interval = interval.getParent();
0918:                    if (!canResize(interval))
0919:                        return false;
0920:                }
0921:                return true;
0922:            }
0923:
0924:            static boolean contentWantResize(LayoutInterval group) {
0925:                boolean subres = false;
0926:                Iterator it = group.getSubIntervals();
0927:                while (it.hasNext()) {
0928:                    if (wantResize((LayoutInterval) it.next())) {
0929:                        subres = true;
0930:                        break;
0931:                    }
0932:                }
0933:                return subres;
0934:            }
0935:
0936:            static int getIntervalCurrentSize(LayoutInterval interval,
0937:                    int dimension) {
0938:                if (!interval.isEmptySpace()) {
0939:                    return interval.getCurrentSpace().size(dimension);
0940:                }
0941:
0942:                int posL;
0943:                int posT;
0944:
0945:                LayoutInterval parent = interval.getParent();
0946:                if (parent.isSequential()) {
0947:                    int index = parent.indexOf(interval);
0948:                    posL = index > 0 ? parent.getSubInterval(index - 1)
0949:                            .getCurrentSpace().positions[dimension][TRAILING]
0950:                            : parent.getCurrentSpace().positions[dimension][LEADING];
0951:                    posT = index + 1 < parent.getSubIntervalCount() ? parent
0952:                            .getSubInterval(index + 1).getCurrentSpace().positions[dimension][LEADING]
0953:                            : parent.getCurrentSpace().positions[dimension][TRAILING];
0954:                } else {
0955:                    posL = parent.getCurrentSpace().positions[dimension][LEADING];
0956:                    posT = parent.getCurrentSpace().positions[dimension][TRAILING];
0957:                }
0958:
0959:                return posT - posL;
0960:
0961:            }
0962:
0963:            /**
0964:             * Computes effective alignment of an interval in its parent. In case of
0965:             * a sequential parent, the effective interval alignment depends on other
0966:             * intervals and their resizability. E.g. if a preceding interval is
0967:             * resizing then the interval is effectivelly "pushed" to the trailing end.
0968:             * If there are no other intervals resizing then the parent alignment is
0969:             * returned. If there are resizing intervals on both sides, or the interval
0970:             * itself is resizing, then the there is no (positive) effective alignment.
0971:             * @return LEADING, TRAILING, or DEFAULT
0972:             */
0973:            static int getEffectiveAlignment(LayoutInterval interval) {
0974:                LayoutInterval parent = interval.getParent();
0975:                if (parent.isParallel())
0976:                    return interval.getAlignment();
0977:
0978:                if (LayoutInterval.wantResize(interval))
0979:                    return DEFAULT;
0980:
0981:                boolean before = true;
0982:                boolean leadingFixed = true;
0983:                boolean trailingFixed = true;
0984:                Iterator it = parent.getSubIntervals();
0985:                do {
0986:                    LayoutInterval li = (LayoutInterval) it.next();
0987:                    if (li == interval) {
0988:                        before = false;
0989:                    } else if (LayoutInterval.wantResize(li)) {
0990:                        if (before)
0991:                            leadingFixed = false;
0992:                        else
0993:                            trailingFixed = false;
0994:                    }
0995:                } while (it.hasNext());
0996:
0997:                if (leadingFixed && !trailingFixed)
0998:                    return LEADING;
0999:                if (!leadingFixed && trailingFixed)
1000:                    return TRAILING;
1001:                if (leadingFixed && trailingFixed)
1002:                    return parent.getAlignment();
1003:
1004:                return DEFAULT; // !leadingFixed && !trailingFixed
1005:            }
1006:
1007:            /**
1008:             * Computes effective alignment of given interval's edge in its direct
1009:             * parent. In case of a sequential parent, the effective interval alignment
1010:             * depends on other intervals and their resizability.
1011:             * @return effective alignment within parent, or DEFAULT in case of
1012:             *         ambiguous alignment in sequential parent
1013:             */
1014:            static int getEffectiveAlignment(LayoutInterval interval, int edge) {
1015:                assert edge == LEADING || edge == TRAILING;
1016:
1017:                boolean wantResize = LayoutInterval.wantResize(interval);
1018:
1019:                LayoutInterval parent = interval.getParent();
1020:                if (parent.isParallel())
1021:                    return wantResize ? edge : interval.getAlignment();
1022:
1023:                int n = parent.getSubIntervalCount();
1024:                int i = edge == LEADING ? 0 : n - 1;
1025:                int d = edge == LEADING ? 1 : -1;
1026:                boolean before = true;
1027:                boolean beforeFixed = true;
1028:                boolean afterFixed = true;
1029:                while (i >= 0 && i < n) {
1030:                    LayoutInterval li = parent.getSubInterval(i);
1031:                    if (li == interval) {
1032:                        before = false;
1033:                    } else if (LayoutInterval.wantResize(li)) {
1034:                        if (before)
1035:                            beforeFixed = false;
1036:                        else
1037:                            afterFixed = false;
1038:                    }
1039:                    i += d;
1040:                }
1041:
1042:                if (beforeFixed && !afterFixed)
1043:                    return edge;
1044:                if (!beforeFixed && afterFixed)
1045:                    return edge ^ 1;
1046:                if (beforeFixed && afterFixed)
1047:                    return wantResize ? edge : parent.getAlignment();
1048:
1049:                return DEFAULT; // !leadingFixed && !trailingFixed
1050:            }
1051:
1052:            /**
1053:             * Computes effective alignment of an interval's edge relatively to given
1054:             * parent.
1055:             * @return effective alignment within parent, or DEFAULT in case of
1056:             *         ambiguous alignment in sequential parent
1057:             */
1058:            static int getEffectiveAlignmentInParent(LayoutInterval interval,
1059:                    LayoutInterval parent, int edge) {
1060:                assert parent.isParentOf(interval);
1061:                int alignment = edge;
1062:                do {
1063:                    alignment = getEffectiveAlignment(interval, alignment);
1064:                    interval = interval.getParent();
1065:                    if (alignment != LEADING && alignment != TRAILING) {
1066:                        while (interval != parent) {
1067:                            if (getEffectiveAlignment(interval) != alignment)
1068:                                return DEFAULT;
1069:                            interval = interval.getParent();
1070:                        }
1071:                    }
1072:                } while (interval != parent);
1073:                return alignment;
1074:            }
1075:
1076:            /**
1077:             * Creates clone of the given interval. Doesn't clone content of groups, nor
1078:             * it sets LayoutComponent. Just the type, alignments and sizes are copied.
1079:             *
1080:             * @param interval interval to be cloned.
1081:             * @param clone interval that should contain cloned data. Can be <code>null</code>.
1082:             * @return shallow clone of the interval.
1083:             */
1084:            static LayoutInterval cloneInterval(LayoutInterval interval,
1085:                    LayoutInterval clone) {
1086:                clone = (clone == null) ? new LayoutInterval(interval.getType())
1087:                        : clone;
1088:                clone.setAlignment(interval.getAlignment());
1089:                clone.setAttributes(interval.getAttributes()
1090:                        & ATTR_PERSISTENT_MASK);
1091:                if (interval.getType() == PARALLEL) {
1092:                    clone.setGroupAlignment(interval.getGroupAlignment());
1093:                }
1094:                clone.setSizes(interval.getMinimumSize(), interval
1095:                        .getPreferredSize(), interval.getMaximumSize());
1096:                if (isDefaultPadding(interval)) {
1097:                    clone.setPaddingType(interval.getPaddingType());
1098:                }
1099:                return clone;
1100:            }
1101:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.