Source Code Cross Referenced for Component.java in  » Ajax » NextApp-Echo2 » nextapp » echo2 » app » 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 » Ajax » NextApp Echo2 » nextapp.echo2.app 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* 
0002:         * This file is part of the Echo Web Application Framework (hereinafter "Echo").
0003:         * Copyright (C) 2002-2005 NextApp, Inc.
0004:         *
0005:         * Version: MPL 1.1/GPL 2.0/LGPL 2.1
0006:         *
0007:         * The contents of this file are subject to the Mozilla Public License Version
0008:         * 1.1 (the "License"); you may not use this file except in compliance with
0009:         * the License. You may obtain a copy of the License at
0010:         * http://www.mozilla.org/MPL/
0011:         *
0012:         * Software distributed under the License is distributed on an "AS IS" basis,
0013:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0014:         * for the specific language governing rights and limitations under the
0015:         * License.
0016:         *
0017:         * Alternatively, the contents of this file may be used under the terms of
0018:         * either the GNU General Public License Version 2 or later (the "GPL"), or
0019:         * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
0020:         * in which case the provisions of the GPL or the LGPL are applicable instead
0021:         * of those above. If you wish to allow use of your version of this file only
0022:         * under the terms of either the GPL or the LGPL, and not to allow others to
0023:         * use your version of this file under the terms of the MPL, indicate your
0024:         * decision by deleting the provisions above and replace them with the notice
0025:         * and other provisions required by the GPL or the LGPL. If you do not delete
0026:         * the provisions above, a recipient may use your version of this file under
0027:         * the terms of any one of the MPL, the GPL or the LGPL.
0028:         */
0029:
0030:        package nextapp.echo2.app;
0031:
0032:        import java.beans.PropertyChangeListener;
0033:        import java.beans.PropertyChangeSupport;
0034:        import java.io.Serializable;
0035:        import java.util.ArrayList;
0036:        import java.util.Iterator;
0037:        import java.util.List;
0038:        import java.util.Locale;
0039:
0040:        import nextapp.echo2.app.event.EventListenerList;
0041:
0042:        /**
0043:         * A representation of an Echo component. This is an abstract base class from
0044:         * which all Echo components are derived.
0045:         * <p>
0046:         * A hierarchy of <code>Component</code> objects is used to represent the
0047:         * state of an application's user interface. A <code>Component</code> may have
0048:         * a single parent <code>Component</code> and may contain zero or more child
0049:         * <code>Component</code>s. Certain <code>Component</code>s may limit the
0050:         * number or type(s) of children which may be added to them, and may even
0051:         * establish requirements for what type(s) of parent <code>Component</code>s
0052:         * they may be added to. In the event that an application attempts to add a
0053:         * child <code>Component</code> to a parent <code>Component</code> in spite
0054:         * of these requirements, an <code>IllegalChildException</code> is thrown.
0055:         * 
0056:         * <h3>Properties and Styles</h3>
0057:         * <p>
0058:         * The state of a single <code>Component</code> is represented by its
0059:         * properties. Properties can be categorized into two types: "style" and
0060:         * "non-style". Style properties are generally used to represent the
0061:         * "look-and-feel" of a Component--information such as colors, fonts, location,
0062:         * and borders. "Non-style" properties are generally used to represent
0063:         * non-stylistic information such as data models, selection models, and locale.
0064:         * <p>
0065:         * "Style Properties" have a special definition because they may be stored in
0066:         * <code>Style</code> or <code>StyleSheet</code> objects instead of as
0067:         * properties of a specific <code>Component</code> instance. Property values
0068:         * contained in a relevant <code>Style</code> or <code>StyleSheet</code>
0069:         * will be used for rendering when the property values are not specified by a
0070:         * <code>Component</code> itself. Style properties are identified by the
0071:         * presence of a public static constant name in a <code>Component</code>
0072:         * implementation with the prefix <code>PROPERTY_</code>. In the base
0073:         * <code>Component</code> class itself there are several examples of style
0074:         * properties, such as <code>PROPERTY_BACKGROUND</code>,<code>PROPERTY_FONT</code>
0075:         * and <code>PROPERTY_LAYOUT_DATA</code>. The rendering application container
0076:         * will use the <code>Component.getRenderProperty()</code> and
0077:         * <code>Component.getRenderIndexedProperty()</code> to retrieve the values of
0078:         * stylistic properties, in order that their values might be obtained from
0079:         * the <code>Component</code>'s shared <code>Style</code> or the
0080:         * <code>ApplicationInstance</code>'s <code>StyleSheet</code> in the event
0081:         * they are not directly set in the <code>Component</code>.
0082:         * <p>
0083:         * A <code>Component</code> implementation should not store the values of
0084:         * style properties as instance variables. Rather, the values of style
0085:         * properties should be stored in the local <code>Style</code> instance, by
0086:         * way of the <code>setProperty()</code> method. The
0087:         * <code>getProperty()</code> method may be used to obtain the value of such
0088:         * properties. Only style properties should be stored using these methods;
0089:         * properties such as models should never be stored using the
0090:         * <code>getProperty()</code>/<code>setProperty()</code> interface.
0091:         * 
0092:         * <h3>Events</h3>
0093:         * <p>
0094:         * Many <code>Component</code>s will provide the capability to register
0095:         * <code>EventListener</code>s to notify interested parties when various
0096:         * state changes occur. The base <code>Component</code> class provides an
0097:         * <code>EventListenerList</code> as a convenient and memory efficient means
0098:         * of storing such listeners. The internal <code>EventListenerList</code> may
0099:         * be obtained using the <code>getEventListenerList()</code> method. The
0100:         * <code>EventListenerList</code> is lazy-created and will only be
0101:         * instantiated on the first invocation of the
0102:         * <code>getEventListenerList()</code> method. If the intent is only to
0103:         * inquire about the state of event listeners without necessarily forcing
0104:         * instantiation of an <code>EventListenerList</code>, the
0105:         * <code>hasEventListenerList()</code> should be queried prior to invoking
0106:         * <code>getEventListenerList()</code>.
0107:         */
0108:        public abstract class Component implements  RenderIdSupport,
0109:                Serializable {
0110:
0111:            /**
0112:             * <code>ArrayList</code> capacity for child storage.
0113:             */
0114:            private static final int CHILD_LIST_CAPACITY = 3;
0115:
0116:            /**
0117:             * Empty array returned by <code>getComponents()</code> when a
0118:             * <code>Component</code> has no children.
0119:             */
0120:            private static final Component[] EMPTY_COMPONENT_ARRAY = new Component[0];
0121:
0122:            /**
0123:             * Flag indicating the <code>Component</code> is enabled.
0124:             */
0125:            private static final int FLAG_ENABLED = 0x1;
0126:
0127:            /**
0128:             * Flag indicating the <code>Component</code> is visible.
0129:             */
0130:            private static final int FLAG_VISIBLE = 0x2;
0131:
0132:            /**
0133:             * Flag indicating the <code>Component</code> will participate in the 
0134:             * focus traversal order.
0135:             */
0136:            private static final int FLAG_FOCUS_TRAVERSAL_PARTICIPANT = 0x4;
0137:
0138:            /**
0139:             * Flag indicating that the <code>Component</code> is currently undergoing
0140:             * registration to an <code>ApplicationInstance</code>.
0141:             */
0142:            private static final int FLAG_REGISTERING = 0x8;
0143:
0144:            private static final int FLAG_INIT_IN_PROGRESS = 0x10;
0145:
0146:            private static final int FLAG_DISPOSE_IN_PROGRESS = 0x20;
0147:
0148:            private static final int FLAG_INITIALIZED = 0x40;
0149:
0150:            /**
0151:             * Flag mask of bits used for storage of focus traversal index.
0152:             */
0153:            private static final int FLAGS_FOCUS_TRAVERSAL_INDEX = 0x7fff0000;
0154:
0155:            public static final String CHILDREN_CHANGED_PROPERTY = "children";
0156:            public static final String ENABLED_CHANGED_PROPERTY = "enabled";
0157:            public static final String FOCUS_TRAVERSAL_INDEX_CHANGED_PROPERTY = "focusTraversalIndex";
0158:            public static final String FOCUS_TRAVERSAL_PARTICIPANT_CHANGED_PROPERTY = "focusTraversalParticipant";
0159:            public static final String LAYOUT_DIRECTION_CHANGED_PROPERTY = "layoutDirection";
0160:            public static final String LOCALE_CHANGED_PROPERTY = "locale";
0161:
0162:            public static final String PROPERTY_BACKGROUND = "background";
0163:            public static final String PROPERTY_FONT = "font";
0164:            public static final String PROPERTY_FOREGROUND = "foreground";
0165:            public static final String PROPERTY_LAYOUT_DATA = "layoutData";
0166:            public static final String STYLE_CHANGED_PROPERTY = "style";
0167:            public static final String STYLE_NAME_CHANGED_PROPERTY = "styleName";
0168:            public static final String VISIBLE_CHANGED_PROPERTY = "visible";
0169:
0170:            //TODO. Doc/move to util.
0171:            private static final boolean isLetter(char ch) {
0172:                return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
0173:            }
0174:
0175:            //TODO. Doc/move to util.
0176:            private static final boolean isLetterOrDigit(char ch) {
0177:                return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')
0178:                        || (ch >= '0' && ch <= '9');
0179:            }
0180:
0181:            /** The <code>ApplicationInstance</code> to which the component is registered. */
0182:            private ApplicationInstance applicationInstance;
0183:
0184:            /** 
0185:             * An ordered collection of references to child components.
0186:             * This object is lazily instantiated. 
0187:             */
0188:            private List children;
0189:
0190:            /**
0191:             * Boolean flags for this component, including enabled state, visibility, 
0192:             * focus traversal participation, and focus traversal index.
0193:             * Multiple booleans are wrapped in a single integer
0194:             * to save memory, since many <code>Component</code>instances will be 
0195:             * created.
0196:             */
0197:            private int flags;
0198:
0199:            /** 
0200:             * A  user-defined identifier for this component.
0201:             * This identifier is not related in any way to <code>renderId</code>. 
0202:             */
0203:            private String id;
0204:
0205:            /** 
0206:             * The layout direction of the component.
0207:             * This property is generally unset, as layout direction information is 
0208:             * normally inherited from the <code>ApplicationInstance</code> or from 
0209:             * an ancestor <code>Component</code> in the hierarchy. 
0210:             */
0211:            private LayoutDirection layoutDirection;
0212:
0213:            /** Listener storage. */
0214:            private EventListenerList listenerList;
0215:
0216:            /** 
0217:             * The locale of the component.
0218:             * This property is generally unset, as locale information is normally
0219:             * inherited from the <code>ApplicationInstance</code> or from an ancestor
0220:             * <code>Component</code> in the hierarchy. 
0221:             */
0222:            private Locale locale;
0223:
0224:            /** Local style data storage for properties directly set on component itself. */
0225:            private MutableStyle localStyle;
0226:
0227:            /** The parent component. */
0228:            private Component parent;
0229:
0230:            /** 
0231:             * The property change event dispatcher.
0232:             * This object is lazily instantiated. 
0233:             */
0234:            private PropertyChangeSupport propertyChangeSupport;
0235:
0236:            /** 
0237:             * A application-wide unique identifier for this component. 
0238:             * This identifier is not related in any way to <code>id</code>. 
0239:             */
0240:            private String renderId;
0241:
0242:            /** Shared style. */
0243:            private Style sharedStyle;
0244:
0245:            /** Name of style to use from application style sheet */
0246:            private String styleName;
0247:
0248:            /**
0249:             * Creates a new <code>Component</code>.
0250:             */
0251:            public Component() {
0252:                super ();
0253:                flags = FLAG_ENABLED | FLAG_VISIBLE
0254:                        | FLAG_FOCUS_TRAVERSAL_PARTICIPANT;
0255:                localStyle = new MutableStyle();
0256:            }
0257:
0258:            /**
0259:             * Adds the specified <code>Component</code> as a child of this 
0260:             * <code>Component</code>.  The child will be added at the greatest
0261:             * index.
0262:             *
0263:             * @param c the child <code>Component</code> to add
0264:             */
0265:            public void add(Component c) {
0266:                add(c, -1);
0267:            }
0268:
0269:            /**
0270:             * Adds the specified <code>Component</code> as the <code>n</code>th 
0271:             * child of this component.
0272:             * All component-add operations use this method to add components.
0273:             * <code>Component</code>s that require notification of all child additions
0274:             * should override this method (making sure to call the superclass' 
0275:             * implementation).
0276:             *
0277:             * @param c the child component to add
0278:             * @param n the index at which to add the child component, or -1 to add the
0279:             *          component at the end
0280:             * @throws IllegalChildException if the child is not allowed to be added
0281:             *         to this component, because it is either not valid for the 
0282:             *         component's state or is of an invalid type
0283:             */
0284:            public void add(Component c, int n) throws IllegalChildException {
0285:
0286:                // Ensure child is acceptable to this component.
0287:                if (!isValidChild(c)) {
0288:                    throw new IllegalChildException(this , c);
0289:                }
0290:
0291:                // Ensure child component finds this component acceptable as a parent.
0292:                if (!c.isValidParent(this )) {
0293:                    throw new IllegalChildException(this , c);
0294:                }
0295:
0296:                // Remove child from it's current parent if required.
0297:                if (c.parent != null) {
0298:                    c.parent.remove(c);
0299:                }
0300:
0301:                // Lazy-create child collection if necessary.
0302:                if (children == null) {
0303:                    children = new ArrayList(CHILD_LIST_CAPACITY);
0304:                }
0305:
0306:                // Connect child to parent.
0307:                c.parent = this ;
0308:                if (n == -1) {
0309:                    children.add(c);
0310:                } else {
0311:                    children.add(n, c);
0312:                }
0313:
0314:                // Flag child as registered.
0315:                if (applicationInstance != null) {
0316:                    c.register(applicationInstance);
0317:                }
0318:
0319:                // Notify PropertyChangeListeners of change.
0320:                firePropertyChange(CHILDREN_CHANGED_PROPERTY, null, c);
0321:
0322:                // Initialize component.
0323:                c.doInit();
0324:            }
0325:
0326:            /**
0327:             * Adds a property change listener to this component.
0328:             *
0329:             * @param l the listener to add
0330:             */
0331:            public void addPropertyChangeListener(PropertyChangeListener l) {
0332:                if (propertyChangeSupport == null) {
0333:                    propertyChangeSupport = new PropertyChangeSupport(this );
0334:                }
0335:                propertyChangeSupport.addPropertyChangeListener(l);
0336:            }
0337:
0338:            /**
0339:             * Internal method to set the render identifier of the<code>Component</code>.
0340:             * This method is invoked by the <code>ApplicationInstance</code>
0341:             * when the component is registered or unregistered, or by manual
0342:             * invocation of <code>setRenderId()</code>.  This method performs no
0343:             * error checking.
0344:             * 
0345:             * @param renderId the new identifier
0346:             * @see #getRenderId()
0347:             * @see #setRenderId()
0348:             */
0349:            void assignRenderId(String renderId) {
0350:                this .renderId = renderId;
0351:            }
0352:
0353:            /**
0354:             * Life-cycle method invoked when the <code>Component</code> is removed 
0355:             * from a registered hierarchy.  Implementations should always invoke
0356:             * <code>super.dispose()</code>.
0357:             * Modifications to the component hierarchy are not allowed within this 
0358:             * method.
0359:             */
0360:            public void dispose() {
0361:            }
0362:
0363:            /**
0364:             * Recursively executes the <code>dispose()</code> life-cycle methods of 
0365:             * this <code>Component</code> and its descendants.
0366:             */
0367:            void doDispose() {
0368:                if (applicationInstance == null) {
0369:                    return;
0370:                }
0371:                if ((flags & (FLAG_INIT_IN_PROGRESS | FLAG_DISPOSE_IN_PROGRESS)) != 0) {
0372:                    throw new IllegalStateException(
0373:                            "Attempt to dispose component when initialize or dispose operation already in progress.");
0374:                }
0375:                flags |= FLAG_DISPOSE_IN_PROGRESS;
0376:                try {
0377:                    if (children != null) {
0378:                        Iterator it = children.iterator();
0379:                        while (it.hasNext()) {
0380:                            ((Component) it.next()).doDispose();
0381:                        }
0382:                    }
0383:                    if ((flags & FLAG_INITIALIZED) == 0) {
0384:                        // Component already disposed.
0385:                        return;
0386:                    }
0387:                    dispose();
0388:                    flags &= ~FLAG_INITIALIZED;
0389:                } finally {
0390:                    flags &= ~FLAG_DISPOSE_IN_PROGRESS;
0391:                }
0392:            }
0393:
0394:            /**
0395:             * Recursively executes the <code>init()</code> life-cycle methods of 
0396:             * this <code>Component</code> and its descendants.
0397:             */
0398:            void doInit() {
0399:                if (applicationInstance == null) {
0400:                    return;
0401:                }
0402:                if ((flags & FLAG_INITIALIZED) != 0) {
0403:                    // Component already initialized.
0404:                    return;
0405:                }
0406:
0407:                if ((flags & (FLAG_INIT_IN_PROGRESS | FLAG_DISPOSE_IN_PROGRESS)) != 0) {
0408:                    throw new IllegalStateException(
0409:                            "Attempt to initialize component when initialize or dispose operation already in progress.");
0410:                }
0411:                flags |= FLAG_INIT_IN_PROGRESS;
0412:                try {
0413:                    init();
0414:                    flags |= FLAG_INITIALIZED;
0415:                    if (children != null) {
0416:                        Iterator it = children.iterator();
0417:                        while (it.hasNext()) {
0418:                            ((Component) it.next()).doInit();
0419:                        }
0420:                    }
0421:                } finally {
0422:                    flags &= ~FLAG_INIT_IN_PROGRESS;
0423:                }
0424:            }
0425:
0426:            /**
0427:             * Reports a bound property change to <code>PropertyChangeListener</code>s
0428:             * and to the <code>ApplicationInstance</code>'s update management system.
0429:             *
0430:             * @param propertyName the name of the changed property
0431:             * @param oldValue the previous value of the property
0432:             * @param newValue the present value of the property
0433:             */
0434:            protected void firePropertyChange(String propertyName,
0435:                    Object oldValue, Object newValue) {
0436:                // Report to PropertyChangeListeners.
0437:                if (propertyChangeSupport != null) {
0438:                    propertyChangeSupport.firePropertyChange(propertyName,
0439:                            oldValue, newValue);
0440:                }
0441:
0442:                // Report to ApplicationInstance.
0443:                // The ApplicationInstance is notified directly in order to reduce
0444:                // per-Component-instance memory requirements, i.e., it enables the 
0445:                // PropertyChangeSupport object to only be instantiated on Components 
0446:                // that have ProperyChangeListeners registered by a third party.
0447:                if (applicationInstance != null) {
0448:                    applicationInstance.notifyComponentPropertyChange(this ,
0449:                            propertyName, oldValue, newValue);
0450:                }
0451:            }
0452:
0453:            /**
0454:             * Returns the <code>ApplicationInstance</code> to which this 
0455:             * <code>Component</code> is registered, or null if it is not currently 
0456:             * registered.
0457:             * 
0458:             * @return the application instance
0459:             */
0460:            public ApplicationInstance getApplicationInstance() {
0461:                return applicationInstance;
0462:            }
0463:
0464:            /**
0465:             * Returns the default/base background color of the <code>Component</code>.
0466:             * This property may not be relevant to certain components, though
0467:             * even in such cases may be useful for setting a default for
0468:             * children.
0469:             *
0470:             * @return the background color
0471:             */
0472:            public Color getBackground() {
0473:                return (Color) localStyle.getProperty(PROPERTY_BACKGROUND);
0474:            }
0475:
0476:            /**
0477:             * Returns the <code>n</code>th immediate child component.
0478:             *
0479:             * @param n the index of the <code>Component</code> to retrieve
0480:             * @return the <code>Component</code> at index <code>n</code>
0481:             * @throws IndexOutOfBoundsException when the index is invalid
0482:             */
0483:            public final Component getComponent(int n) {
0484:                if (children == null) {
0485:                    throw new IndexOutOfBoundsException();
0486:                }
0487:
0488:                return (Component) children.get(n);
0489:            }
0490:
0491:            /**
0492:             * Recursively searches for the component with the specified id
0493:             * by querying this component and its descendants.
0494:             * The id value is that retrieved and set via the <code>getId()</code>
0495:             * and <code>setId()</code> methods.  This method is in no way
0496:             * related to <code>renderId</code>s.
0497:             * 
0498:             * @param id the user-defined id of the component to be retrieved
0499:             * @return the component with the specified id, if it either is this
0500:             *         component or is a descendant of it, or null otherwise
0501:             */
0502:            public final Component getComponent(String id) {
0503:                if (id.equals(this .id)) {
0504:                    return this ;
0505:                }
0506:                if (children == null) {
0507:                    return null;
0508:                }
0509:                Iterator it = children.iterator();
0510:                while (it.hasNext()) {
0511:                    Component testComponent = (Component) it.next();
0512:                    Component targetComponent = testComponent.getComponent(id);
0513:                    if (targetComponent != null) {
0514:                        return targetComponent;
0515:                    }
0516:                }
0517:                return null;
0518:            }
0519:
0520:            /**
0521:             * Returns the number of immediate child <code>Component</code>s.
0522:             *
0523:             * @return the number of immediate child <code>Component</code>s
0524:             */
0525:            public final int getComponentCount() {
0526:                if (children == null) {
0527:                    return 0;
0528:                } else {
0529:                    return children.size();
0530:                }
0531:            }
0532:
0533:            /**
0534:             * Returns an array of all immediate child <code>Component</code>s.
0535:             *
0536:             * @return an array of all immediate child <code>Component</code>s
0537:             */
0538:            public final Component[] getComponents() {
0539:                if (children == null) {
0540:                    return EMPTY_COMPONENT_ARRAY;
0541:                } else {
0542:                    return (Component[]) children
0543:                            .toArray(new Component[children.size()]);
0544:                }
0545:            }
0546:
0547:            /**
0548:             * Returns the local <code>EventListenerList</code>.
0549:             * The listener list is lazily created; invoking this method will 
0550:             * create the <code>EventListenerList</code> if required.
0551:             * 
0552:             * @return the listener list
0553:             */
0554:            protected EventListenerList getEventListenerList() {
0555:                if (listenerList == null) {
0556:                    listenerList = new EventListenerList();
0557:                }
0558:                return listenerList;
0559:            }
0560:
0561:            /**
0562:             * Returns the focus traversal (tab) index of the component.
0563:             * Components with numerically lower indices will be focused before
0564:             * components with numerically higher indices.  The value 0 has special
0565:             * meaning, in that components with a value of 0 will be focused last.
0566:             * The default value is 0.
0567:             * 
0568:             * @return the focus traversal index, a value between 0 and 32767
0569:             */
0570:            public final int getFocusTraversalIndex() {
0571:                return (flags & FLAGS_FOCUS_TRAVERSAL_INDEX) >> 16;
0572:            }
0573:
0574:            /**
0575:             * Returns the default/base font of the component.
0576:             * This property may not be relevant to certain components, though
0577:             * even in such cases may be useful for setting a default for
0578:             * children.
0579:             *
0580:             * @return the font
0581:             */
0582:            public Font getFont() {
0583:                return (Font) localStyle.getProperty(PROPERTY_FONT);
0584:            }
0585:
0586:            /**
0587:             * Returns the default/base foreground color of the <code>Component</code>.
0588:             * This property may not be relevant to certain components, though
0589:             * even in such cases may be useful for setting a default for 
0590:             * children.
0591:             *
0592:             * @return the foreground color
0593:             */
0594:            public Color getForeground() {
0595:                return (Color) localStyle.getProperty(PROPERTY_FOREGROUND);
0596:            }
0597:
0598:            /**
0599:             * Returns the user-defined identifier of the <code>Component</code>.
0600:             * Note that the user defined identifier has no relation to the
0601:             * <code>renderId</code>.
0602:             * 
0603:             * @return the user-defined identifier
0604:             */
0605:            public String getId() {
0606:                return id;
0607:            }
0608:
0609:            /**
0610:             * Returns the value of the specified indexed property.
0611:             * This method is generally used only internally by a 
0612:             * <code>Component</code>, however there are exceptions.
0613:             * The more specific <code>getXXX()</code> methods to retrieve 
0614:             * property values from a <code>Component</code> whenever
0615:             * possible.
0616:             * See the class-level documentation for a more detailed 
0617:             * explanation of the use of this method.
0618:             * 
0619:             * @param propertyName the property name
0620:             * @param propertyIndex the property index
0621:             * @return the property value
0622:             */
0623:            public final Object getIndexedProperty(String propertyName,
0624:                    int propertyIndex) {
0625:                return localStyle.getIndexedProperty(propertyName,
0626:                        propertyIndex);
0627:            }
0628:
0629:            /**
0630:             * Returns the <code>LayoutData</code> object used to describe how this
0631:             * <code>Component</code> should be laid out within its parent container.
0632:             * 
0633:             * @return the layout data, or null if unset
0634:             * @see LayoutData
0635:             */
0636:            public LayoutData getLayoutData() {
0637:                return (LayoutData) localStyle
0638:                        .getProperty(PROPERTY_LAYOUT_DATA);
0639:            }
0640:
0641:            /**
0642:             * Returns the specific layout direction setting of this component, if any.
0643:             * This method will return null unless a <code>LayoutDirection</code> is
0644:             * specifically set on <strong>this</strong> <code>Component</code>.
0645:             * 
0646:             * @return the layout direction property of <strong>this</strong>
0647:             *         <code>Component</code>
0648:             * @see #getRenderLayoutDirection()
0649:             */
0650:            public LayoutDirection getLayoutDirection() {
0651:                return layoutDirection;
0652:            }
0653:
0654:            /**
0655:             * Returns the specific locale setting of this component, if any.
0656:             * This method will return null unless a <code>Locale</code> is
0657:             * specifically set on <strong>this</strong> <code>Component</code>.
0658:             * 
0659:             * @return the locale property of <strong>this</strong> 
0660:             *         <code>Component</code>
0661:             * @see #getRenderLocale()
0662:             */
0663:            public Locale getLocale() {
0664:                return locale;
0665:            }
0666:
0667:            /**
0668:             * Returns the parent component.
0669:             * 
0670:             * @return the parent component, or null if this component has no parent
0671:             */
0672:            public final Component getParent() {
0673:                return parent;
0674:            }
0675:
0676:            /**
0677:             * Returns the value of the specified property.
0678:             * This method is generally used only internally by a 
0679:             * <code>Component</code>, however there are exceptions.
0680:             * The more specific <code>getXXX()</code> methods to retrieve 
0681:             * property values from a <code>Component</code> whenever
0682:             * possible.
0683:             * See the class-level documentation for a more detailed 
0684:             * explanation of the use of this method.
0685:             * 
0686:             * @param propertyName the property name
0687:             * @return the property value
0688:             */
0689:            public final Object getProperty(String propertyName) {
0690:                return localStyle.getProperty(propertyName);
0691:            }
0692:
0693:            /**
0694:             * Returns the render id of this component.  
0695:             * This id is only guaranteed to be unique within 
0696:             * the <code>ApplicationInstance</code> to which this component is 
0697:             * registered.  This method returns null in the event that the 
0698:             * component is not registered to an <code>ApplicationInstance</code>.
0699:             * 
0700:             * @return the <code>ApplicationInstance</code>-wide unique id of this 
0701:             *         component
0702:             * @see nextapp.echo2.app.RenderIdSupport#getRenderId()
0703:             */
0704:            public String getRenderId() {
0705:                return renderId;
0706:            }
0707:
0708:            /**
0709:             * Determines the &quot;rendered state&quot; of an indexed property.
0710:             * The rendered state is determined by first determining if the given
0711:             * property is locally set on this <code>Component</code>, and returning
0712:             * it in that case.  If the property state is not set locally, the 
0713:             * shared <code>Style</code> assigned to this component will be queried
0714:             * for the property value.  If the property state is not set in the
0715:             * shared <code>Style</code>, the <code>StyleSheet</code> of the
0716:             * <code>ApplicationInstance</code> to which this <code>Component</code>
0717:             * is registered will be queried for the property value.
0718:             * In the event the property is not set in any of these resources,
0719:             * null is returned.
0720:             * <p>
0721:             * The application container will invoke this method
0722:             * rather than individual property getter methods to determine the state
0723:             * of properties when rendering.
0724:             * 
0725:             * @param propertyName the name of the property
0726:             * @return the rendered property value
0727:             */
0728:            public final Object getRenderIndexedProperty(String propertyName,
0729:                    int propertyIndex) {
0730:                return getRenderIndexedProperty(propertyName, propertyIndex,
0731:                        null);
0732:            }
0733:
0734:            /**
0735:             * Determines the &quot;rendered state&quot; of an indexed property.
0736:             * The rendered state is determined by first determining if the given
0737:             * property is locally set on this <code>Component</code>, and returning
0738:             * it in that case.  If the property state is not set locally, the 
0739:             * shared <code>Style</code> assigned to this component will be queried
0740:             * for the property value.  If the property state is not set in the
0741:             * shared <code>Style</code>, the <code>StyleSheet</code> of the
0742:             * <code>ApplicationInstance</code> to which this <code>Component</code>
0743:             * is registered will be queried for the property value.
0744:             * In the event the property is not set in any of these resources,
0745:             * <code>defaultValue</code> is returned.
0746:             * 
0747:             * @param propertyName the name of the property
0748:             * @param defaultValue the value to be returned if the property is not set
0749:             * @return the property state
0750:             */
0751:            public final Object getRenderIndexedProperty(String propertyName,
0752:                    int propertyIndex, Object defaultValue) {
0753:                if (localStyle
0754:                        .isIndexedPropertySet(propertyName, propertyIndex)) {
0755:                    // Return local style value.
0756:                    return localStyle.getIndexedProperty(propertyName,
0757:                            propertyIndex);
0758:                } else if (sharedStyle != null
0759:                        && sharedStyle.isIndexedPropertySet(propertyName,
0760:                                propertyIndex)) {
0761:                    // Return style value specified in shared style.
0762:                    return sharedStyle.getIndexedProperty(propertyName,
0763:                            propertyIndex);
0764:                } else {
0765:                    if (applicationInstance != null) {
0766:                        Style applicationStyle = applicationInstance.getStyle(
0767:                                getClass(), styleName);
0768:                        if (applicationStyle != null
0769:                                && applicationStyle.isIndexedPropertySet(
0770:                                        propertyName, propertyIndex)) {
0771:                            // Return style value specified in application.
0772:                            return applicationStyle.getIndexedProperty(
0773:                                    propertyName, propertyIndex);
0774:                        }
0775:                    }
0776:                    return defaultValue;
0777:                }
0778:            }
0779:
0780:            /**
0781:             * Returns the rendered <code>LayoutDirection</code> of the
0782:             * <code>Component</code>.
0783:             * 
0784:             * @return the layout direction of this component
0785:             */
0786:            public final LayoutDirection getRenderLayoutDirection() {
0787:                if (layoutDirection == null) {
0788:                    if (locale == null) {
0789:                        if (parent == null) {
0790:                            if (applicationInstance == null) {
0791:                                return null;
0792:                            } else {
0793:                                return applicationInstance.getLayoutDirection();
0794:                            }
0795:                        } else {
0796:                            return parent.getRenderLayoutDirection();
0797:                        }
0798:                    } else {
0799:                        return LayoutDirection.forLocale(locale);
0800:                    }
0801:                } else {
0802:                    return layoutDirection;
0803:                }
0804:            }
0805:
0806:            /**
0807:             * Returns the rendered <code>Locale</code> of the <code>Component</code>.
0808:             * If this <code>Component</code> does not itself specify a locale, its
0809:             * ancestors will be queried recursively until a <code>Component</code>
0810:             * providing a <code>Locale</code> is found. If no ancestors have
0811:             * <code>Locale</code>s set, the <code>ApplicationInstance</code>'s
0812:             * locale will be returned. In the event that no locale information is
0813:             * available from the ancestral hierarchy of <code>Component</code>s and
0814:             * no <code>ApplicationInstance</code> is registered, null is returned.
0815:             * 
0816:             * @return the locale for this component
0817:             */
0818:            public final Locale getRenderLocale() {
0819:                if (locale == null) {
0820:                    if (parent == null) {
0821:                        if (applicationInstance == null) {
0822:                            return null;
0823:                        } else {
0824:                            return applicationInstance.getLocale();
0825:                        }
0826:                    } else {
0827:                        return parent.getRenderLocale();
0828:                    }
0829:                } else {
0830:                    return locale;
0831:                }
0832:            }
0833:
0834:            /**
0835:             * Determines the &quot;rendered state&quot; of a property.
0836:             * The rendered state is determined by first determining if the given
0837:             * property is locally set on this <code>Component</code>, and returning
0838:             * it in that case.  If the property state is not set locally, the 
0839:             * shared <code>Style</code> assigned to this component will be queried
0840:             * for the property value.  If the property state is not set in the
0841:             * shared <code>Style</code>, the <code>StyleSheet</code> of the
0842:             * <code>ApplicationInstance</code> to which this <code>Component</code>
0843:             * is registered will be queried for the property value.
0844:             * In the event the property is not set in any of these resources,
0845:             * null is returned.
0846:             * <p>
0847:             * The application container will invoke this method
0848:             * rather than individual property getter methods to determine the state
0849:             * of properties when rendering.
0850:             * 
0851:             * @param propertyName the name of the property
0852:             * @return the rendered property value
0853:             */
0854:            public final Object getRenderProperty(String propertyName) {
0855:                return getRenderProperty(propertyName, null);
0856:            }
0857:
0858:            /**
0859:             * Determines the &quot;rendered state&quot; of a property.
0860:             * The rendered state is determined by first determining if the given
0861:             * property is locally set on this <code>Component</code>, and returning
0862:             * it in that case.  If the property state is not set locally, the 
0863:             * shared <code>Style</code> assigned to this component will be queried
0864:             * for the property value.  If the property state is not set in the
0865:             * shared <code>Style</code>, the <code>StyleSheet</code> of the
0866:             * <code>ApplicationInstance</code> to which this <code>Component</code>
0867:             * is registered will be queried for the property value.
0868:             * In the event the property is not set in any of these resources,
0869:             * <code>defaultValue</code> is returned.
0870:             * 
0871:             * @param propertyName the name of the property
0872:             * @param defaultValue the value to be returned if the property is not set
0873:             * @return the property state
0874:             */
0875:            public final Object getRenderProperty(String propertyName,
0876:                    Object defaultValue) {
0877:                Object propertyValue = localStyle.getProperty(propertyName);
0878:                if (propertyValue != null) {
0879:                    return propertyValue;
0880:                }
0881:                if (sharedStyle != null) {
0882:                    propertyValue = sharedStyle.getProperty(propertyName);
0883:                    if (propertyValue != null) {
0884:                        return propertyValue;
0885:                    }
0886:                }
0887:                if (applicationInstance != null) {
0888:                    Style applicationStyle = applicationInstance.getStyle(
0889:                            getClass(), styleName);
0890:                    if (applicationStyle != null) {
0891:                        // Return style value specified in application.
0892:                        propertyValue = applicationStyle
0893:                                .getProperty(propertyName);
0894:                        if (propertyValue != null) {
0895:                            return propertyValue;
0896:                        }
0897:                    }
0898:                }
0899:                return defaultValue;
0900:            }
0901:
0902:            /**
0903:             * Returns the shared <code>Style</code> object assigned to this 
0904:             * <code>Component</code>.
0905:             * As its name implies, the <strong>shared</strong> <code>Style</code> 
0906:             * may be shared amongst multiple <code>Component</code>s.
0907:             * Style properties will be rendered from the specified <code>Style</code>
0908:             * when they are not specified locally in the <code>Component</code> 
0909:             * itself.
0910:             * 
0911:             * @return the shared <code>Style</code>
0912:             */
0913:            public final Style getStyle() {
0914:                return sharedStyle;
0915:            }
0916:
0917:            /**
0918:             * Returns the name of the <code>Style</code> in the
0919:             * <code>ApplicationInstance</code>'s<code>StyleSheet</code> from
0920:             * which the renderer will retrieve properties. The renderer will only query
0921:             * the <code>StyleSheet</code> when properties are not specified directly
0922:             * by the <code>Component</code> or by the <code>Component</code>'s
0923:             * shared <code>Style</code>.
0924:             * 
0925:             * @return the style name
0926:             */
0927:            public final String getStyleName() {
0928:                return styleName;
0929:            }
0930:
0931:            /**
0932:             * Returns the <code>n</code>th immediate <strong>visible</strong> 
0933:             * child <code>Component</code>.
0934:             *
0935:             * @param n the index of the <code>Component</code> to retrieve
0936:             * @return the <code>Component</code> at index <code>n</code>
0937:             * @throws IndexOutOfBoundsException when the index is invalid
0938:             */
0939:            public final Component getVisibleComponent(int n) {
0940:                if (children == null) {
0941:                    throw new IndexOutOfBoundsException(Integer.toString(n));
0942:                }
0943:                int visibleComponentCount = 0;
0944:                Component component = null;
0945:                Iterator it = children.iterator();
0946:                while (visibleComponentCount <= n) {
0947:                    if (!it.hasNext()) {
0948:                        throw new IndexOutOfBoundsException(Integer.toString(n));
0949:                    }
0950:                    component = (Component) it.next();
0951:                    if (component.isVisible()) {
0952:                        ++visibleComponentCount;
0953:                    }
0954:                }
0955:                return component;
0956:            }
0957:
0958:            /**
0959:             * Returns the number of <strong>visible</strong> immediate child 
0960:             * <code>Component</code>s.
0961:             *
0962:             * @return the number of <strong>visible</strong> immediate child 
0963:             *         <code>Component</code>s
0964:             */
0965:            public final int getVisibleComponentCount() {
0966:                if (children == null) {
0967:                    return 0;
0968:                } else {
0969:                    int visibleComponentCount = 0;
0970:                    Iterator it = children.iterator();
0971:                    while (it.hasNext()) {
0972:                        Component component = (Component) it.next();
0973:                        if (component.isVisible()) {
0974:                            ++visibleComponentCount;
0975:                        }
0976:                    }
0977:                    return visibleComponentCount;
0978:                }
0979:            }
0980:
0981:            /**
0982:             * Returns an array of all <strong>visible</strong> immediate child 
0983:             * <code>Component</code>s.
0984:             *
0985:             * @return an array of all <strong>visible</strong> immediate child 
0986:             *         <code>Component</code>s
0987:             */
0988:            public final Component[] getVisibleComponents() {
0989:                if (children == null) {
0990:                    return EMPTY_COMPONENT_ARRAY;
0991:                } else {
0992:                    Iterator it = children.iterator();
0993:                    List visibleChildList = new ArrayList();
0994:                    while (it.hasNext()) {
0995:                        Component component = (Component) it.next();
0996:                        if (component.isVisible()) {
0997:                            visibleChildList.add(component);
0998:                        }
0999:                    }
1000:                    return (Component[]) visibleChildList
1001:                            .toArray(new Component[visibleChildList.size()]);
1002:                }
1003:            }
1004:
1005:            /**
1006:             * Determines if a local <code>EventListenerList</code> exists.
1007:             * If no listener list exists, it can be assured that there are thus no
1008:             * listeners registered to it.  This method should be invoked by event
1009:             * firing code prior to invoking <code>getListenerList()</code> to avoid
1010:             * unnecessary creation of an <code>EventListenerList</code> in response
1011:             * to their query.
1012:             * 
1013:             * @return true if a local <code>EventListenerList</code> exists
1014:             */
1015:            protected boolean hasEventListenerList() {
1016:                return listenerList != null;
1017:            }
1018:
1019:            /**
1020:             * Determines the index of the given <code>Component</code> within the 
1021:             * children of this <code>Component</code>.  If the given 
1022:             * <code>Component</code> is not a child, <code>-1</code> is returned.
1023:             * 
1024:             * @param c the <code>Component</code> to analyze
1025:             * @return the index of the specified <code>Component</code> amongst the 
1026:             *         children of this <code>Component</code>
1027:             */
1028:            public final int indexOf(Component c) {
1029:                return children == null ? -1 : children.indexOf(c);
1030:            }
1031:
1032:            /**
1033:             * Life-cycle method invoked when the <code>Component</code> is added 
1034:             * to a registered hierarchy.  Implementations should always invoke
1035:             * <code>super.init()</code>.
1036:             * Modifications to the component hierarchy are not allowed within this 
1037:             * method.
1038:             */
1039:            public void init() {
1040:            }
1041:
1042:            /**
1043:             * Determines if this <code>Component</code> is or is an ancestor of 
1044:             * the specified <code>Component</code>.
1045:             * 
1046:             * @param c the <code>Component</code> to test for ancestry
1047:             * @return true if this <code>Component</code> is an ancestor of the 
1048:             *         specified <code>Component</code>
1049:             */
1050:            public final boolean isAncestorOf(Component c) {
1051:                while (c != null && c != this ) {
1052:                    c = c.parent;
1053:                }
1054:                return c == this ;
1055:            }
1056:
1057:            /**
1058:             * Determines the enabled state of this <code>Component</code>.
1059:             * Disabled<code>Component</code>s are not eligible to receive user input.
1060:             * The application container may render disabled components with an altered
1061:             * appearance. 
1062:             * 
1063:             * @return true if the component is enabled
1064:             * @see #verifyInput(java.lang.String, java.lang.Object)
1065:             */
1066:            public final boolean isEnabled() {
1067:                return (flags & FLAG_ENABLED) != 0;
1068:            }
1069:
1070:            /**
1071:             * Determines if the <code>Component</code> participates in (tab) focus 
1072:             * traversal.
1073:             * 
1074:             * @return true if the <code>Component</code> participates in focus 
1075:             *         traversal
1076:             */
1077:            public boolean isFocusTraversalParticipant() {
1078:                return (flags & FLAG_FOCUS_TRAVERSAL_PARTICIPANT) != 0;
1079:            }
1080:
1081:            /**
1082:             * Determines if the <code>Component</code> is registered to an 
1083:             * <code>ApplicationInstance</code>.
1084:             * 
1085:             * @return true if the <code>Component</code> is registered to an 
1086:             *         <code>ApplicationInstance</code>
1087:             */
1088:            public final boolean isRegistered() {
1089:                return applicationInstance != null;
1090:            }
1091:
1092:            /**
1093:             * Determines whether this <code>Component</code> should be rendered with
1094:             * an enabled state.
1095:             * Disabled<code>Component</code>s are not eligible to receive user input.
1096:             * The application container may render disabled components with an altered
1097:             * appearance. 
1098:             * 
1099:             * @return true if the component should be rendered enabled.
1100:             */
1101:            public final boolean isRenderEnabled() {
1102:                Component component = this ;
1103:                while (component != null) {
1104:                    if ((component.flags & FLAG_ENABLED) == 0) {
1105:                        return false;
1106:                    }
1107:                    component = component.parent;
1108:                }
1109:                return true;
1110:            }
1111:
1112:            /**
1113:             * Determines if the <code>Component</code> and all of its parents are
1114:             * visible.
1115:             * 
1116:             * @return true if the <code>Component</code> is recursively visible
1117:             */
1118:            public final boolean isRenderVisible() {
1119:                Component component = this ;
1120:                while (component != null) {
1121:                    if ((component.flags & FLAG_VISIBLE) == 0) {
1122:                        return false;
1123:                    }
1124:                    component = component.parent;
1125:                }
1126:                return true;
1127:            }
1128:
1129:            /**
1130:             * Determines if a given <code>Component</code> is valid to be added as a
1131:             * child to this <code>Component</code>. Default implementation always
1132:             * returns true, may be overridden to provide specific behavior.
1133:             * 
1134:             * @param child the <code>Component</code> to evaluate as a child
1135:             * @return true if the <code>Component</code> is a valid child
1136:             */
1137:            public boolean isValidChild(Component child) {
1138:                return true;
1139:            }
1140:
1141:            /**
1142:             * Determines if this <code>Component</code> is valid to be added as a
1143:             * child of the given parent <code>Component</code>. Default
1144:             * implementation always returns true, may be overridden to provide specific
1145:             * behavior.
1146:             * 
1147:             * @param parent the <code>Component</code> to evaluate as a parent
1148:             * @return true if the <code>Component</code> is a valid parent
1149:             */
1150:            public boolean isValidParent(Component parent) {
1151:                return true;
1152:            }
1153:
1154:            /**
1155:             * Returns the visibility state of this <code>Component</code>.
1156:             * Non-visible components will not be seen by the rendering application
1157:             * container, and will not be rendered in any fashion on the user 
1158:             * interface.  Rendering Application Containers should ensure that no 
1159:             * information about the state of an invisible component is provided to 
1160:             * the user interface for security purposes. 
1161:             *
1162:             * @return the visibility state of this <code>Component</code>
1163:             */
1164:            public final boolean isVisible() {
1165:                return (FLAG_VISIBLE & flags) != 0;
1166:            }
1167:
1168:            /**
1169:             * Processes client input specific to the <code>Component</code> 
1170:             * received from the <code>UpdateManager</code>.
1171:             * Derivative implementations should take care to invoke 
1172:             * <code>super.processInput()</code>.
1173:             * 
1174:             * @param inputName the name of the input
1175:             * @param inputValue the value of the input
1176:             * @see nextapp.echo2.app.update.UpdateManager
1177:             */
1178:            public void processInput(String inputName, Object inputValue) {
1179:            }
1180:
1181:            /**
1182:             * Sets the <code>ApplicationInstance</code> to which this component is
1183:             * registered.
1184:             * <p>
1185:             * The <code>ApplicationInstance</code> to which a component is registered
1186:             * may not be changed directly from one to another, i.e., if the component
1187:             * is registered to instance "A" and an attempt is made to set it to
1188:             * instance "B", an <code>IllegalStateException</code> will be thrown. In
1189:             * order to change the instance to which a component is registered, the
1190:             * instance must first be set to null.
1191:             * 
1192:             * @param newValue the new <code>ApplicationInstance</code>
1193:             * @throws IllegalStateException in the event that an attempt is made to
1194:             *         re-add a <code>Component</code> to a hierarchy during a 
1195:             *         <code>dispose()</code> operation or if an attempt is made to
1196:             *         remove a <code>Component</code> during an <code>init()</code>
1197:             *         operation.
1198:             */
1199:            void register(ApplicationInstance newValue) {
1200:                // Verifying 'registering' flag is not set.
1201:                if ((flags & FLAG_REGISTERING) != 0) {
1202:                    throw new IllegalStateException(
1203:                            "Illegal attempt to register/unregister Component from within invocation of registration change "
1204:                                    + "life-cycle method.");
1205:                }
1206:                try {
1207:                    // Set 'registering' flag.
1208:                    flags |= FLAG_REGISTERING;
1209:
1210:                    if (applicationInstance == newValue) {
1211:                        // Child component added/removed during init()/dispose(): do nothing.
1212:                        return;
1213:                    }
1214:
1215:                    if (applicationInstance != null && newValue != null) {
1216:                        throw new IllegalStateException(
1217:                                "Illegal attempt to re-register Component to alternate ApplicationInstance.");
1218:                    }
1219:
1220:                    if (newValue == null) { // unregistering
1221:                        if (children != null) {
1222:                            Iterator it = children.iterator();
1223:                            while (it.hasNext()) {
1224:                                ((Component) it.next()).register(null); // Recursively unregister children.
1225:                            }
1226:                        }
1227:
1228:                        applicationInstance.unregisterComponent(this );
1229:                    }
1230:
1231:                    applicationInstance = newValue;
1232:
1233:                    if (newValue != null) { // registering
1234:                        applicationInstance.registerComponent(this );
1235:
1236:                        if (children != null) {
1237:                            Iterator it = children.iterator();
1238:                            while (it.hasNext()) {
1239:                                ((Component) it.next()).register(newValue); // Recursively register children.
1240:                            }
1241:                        }
1242:                    }
1243:                } finally {
1244:                    // Clear 'registering' flag.
1245:                    flags &= ~FLAG_REGISTERING;
1246:                }
1247:            }
1248:
1249:            /**
1250:             * Removes the specified child <code>Component</code> from this
1251:             * <code>Component</code>.
1252:             * <p>
1253:             * All <code>Component</code> remove operations use this method to 
1254:             * remove <code>Component</code>s. <code>Component</code>s that require 
1255:             * notification of all child removals should 
1256:             * override this method (while ensuring to call the superclass' 
1257:             * implementation).
1258:             * 
1259:             * @param c the child <code>Component</code> to remove
1260:             */
1261:            public void remove(Component c) {
1262:
1263:                if (children == null || !children.contains(c)) {
1264:                    // Do-nothing if component is not a child.
1265:                    return;
1266:                }
1267:
1268:                c.doDispose();
1269:
1270:                // Deregister child.
1271:                if (applicationInstance != null) {
1272:                    c.register(null);
1273:                }
1274:
1275:                // Dissolve references between parent and child.
1276:                children.remove(c);
1277:                c.parent = null;
1278:
1279:                // Notify PropertyChangeListeners of change.
1280:                firePropertyChange(CHILDREN_CHANGED_PROPERTY, c, null);
1281:            }
1282:
1283:            /**
1284:             * Removes the <code>Component</code> at the <code>n</code>th index.
1285:             *
1286:             * @param n the index of the child <code>Component</code> to remove
1287:             * @throws IndexOutOfBoundsException if the index is not valid
1288:             */
1289:            public void remove(int n) {
1290:                if (children == null) {
1291:                    throw new IndexOutOfBoundsException();
1292:                }
1293:                remove(getComponent(n));
1294:            }
1295:
1296:            /**
1297:             * Removes all child <code>Component</code>s.
1298:             */
1299:            public void removeAll() {
1300:                if (children != null) {
1301:                    while (children.size() > 0) {
1302:                        Component c = (Component) children
1303:                                .get(children.size() - 1);
1304:                        remove(c);
1305:                    }
1306:                    children = null;
1307:                }
1308:            }
1309:
1310:            /**
1311:             * Removes a property change listener from this <code>Component</code>.
1312:             *
1313:             * @param l the listener to be removed
1314:             */
1315:            public void removePropertyChangeListener(PropertyChangeListener l) {
1316:                if (propertyChangeSupport != null) {
1317:                    propertyChangeSupport.removePropertyChangeListener(l);
1318:                }
1319:            }
1320:
1321:            /**
1322:             * Sets the default background color of the <code>Component</code>.
1323:             * 
1324:             * @param newValue the new background <code>Color</code>
1325:             */
1326:            public void setBackground(Color newValue) {
1327:                setProperty(PROPERTY_BACKGROUND, newValue);
1328:            }
1329:
1330:            /**
1331:             * Sets the enabled state of the <code>Component</code>.
1332:             * 
1333:             * @param newValue the new state
1334:             * @see #isEnabled
1335:             */
1336:            public void setEnabled(boolean newValue) {
1337:                boolean oldValue = (flags & FLAG_ENABLED) != 0;
1338:                if (oldValue != newValue) {
1339:                    flags ^= FLAG_ENABLED; // Toggle FLAG_ENABLED bit.
1340:                    firePropertyChange(ENABLED_CHANGED_PROPERTY, new Boolean(
1341:                            oldValue), new Boolean(newValue));
1342:                }
1343:            }
1344:
1345:            /**
1346:             * Sets the focus traversal (tab) index of the component.
1347:             * 
1348:             * @param newValue the new focus traversal index
1349:             * @see #getFocusTraversalIndex()
1350:             */
1351:            public void setFocusTraversalIndex(int newValue) {
1352:                int oldValue = getFocusTraversalIndex();
1353:                newValue &= 0x7fff;
1354:                flags = flags & ((~FLAGS_FOCUS_TRAVERSAL_INDEX))
1355:                        | (newValue << 16);
1356:                firePropertyChange(FOCUS_TRAVERSAL_INDEX_CHANGED_PROPERTY,
1357:                        new Integer(oldValue), new Integer(newValue));
1358:            }
1359:
1360:            /**
1361:             * Sets whether the component participates in the focus traversal order 
1362:             * (tab order).
1363:             * 
1364:             * @param newValue true if the component participates in the focus 
1365:             *        traversal order
1366:             */
1367:            public void setFocusTraversalParticipant(boolean newValue) {
1368:                boolean oldValue = isFocusTraversalParticipant();
1369:                if (oldValue != newValue) {
1370:                    flags ^= FLAG_FOCUS_TRAVERSAL_PARTICIPANT; // Toggle FLAG_FOCUS_TRAVERSAL_PARTICIPANT bit.
1371:                    firePropertyChange(
1372:                            FOCUS_TRAVERSAL_PARTICIPANT_CHANGED_PROPERTY,
1373:                            new Boolean(oldValue), new Boolean(newValue));
1374:                }
1375:            }
1376:
1377:            /**
1378:             * Sets the default text font of the <code>Component</code>.
1379:             * 
1380:             * @param newValue the new <code>Font</code>
1381:             */
1382:            public void setFont(Font newValue) {
1383:                setProperty(PROPERTY_FONT, newValue);
1384:            }
1385:
1386:            /**
1387:             * Sets the default foreground color of the <code>Component</code>.
1388:             * 
1389:             * @param newValue the new foreground <code>Color</code>
1390:             */
1391:            public void setForeground(Color newValue) {
1392:                setProperty(PROPERTY_FOREGROUND, newValue);
1393:            }
1394:
1395:            /**
1396:             * Sets a user-defined identifier for this <code>Component</code>.
1397:             * 
1398:             * @param id the new identifier
1399:             */
1400:            public void setId(String id) {
1401:                this .id = id;
1402:            }
1403:
1404:            /**
1405:             * Sets a generic indexed property of the <code>Component</code>.
1406:             * The value will be stored in this <code>Component</code>'s local style.
1407:             * 
1408:             * @param propertyName the name of the property
1409:             * @param propertyIndex the index of the property
1410:             * @param newValue the value of the property
1411:             * 
1412:             * @see #getIndexedProperty(java.lang.String, int)
1413:             */
1414:            public void setIndexedProperty(String propertyName,
1415:                    int propertyIndex, Object newValue) {
1416:                localStyle.setIndexedProperty(propertyName, propertyIndex,
1417:                        newValue);
1418:                firePropertyChange(propertyName, null, null);
1419:            }
1420:
1421:            /**
1422:             * Sets the <code>LayoutData</code> of this <code>Component</code>.
1423:             * A <code>LayoutData</code> implementation describes how this
1424:             * <code>Component</code> is laid out within/interacts with its 
1425:             * containing parent <code>Component</code>.
1426:             * 
1427:             * @param newValue the new <code>LayoutData</code>
1428:             * @see LayoutData
1429:             */
1430:            public void setLayoutData(LayoutData newValue) {
1431:                setProperty(PROPERTY_LAYOUT_DATA, newValue);
1432:            }
1433:
1434:            /**
1435:             * Sets the <code>LayoutDirection</code> of this <code>Component</code>,
1436:             * describing whether content is rendered left-to-right or right-to-left.
1437:             * 
1438:             * @param newValue the new <code>LayoutDirection</code>. 
1439:             */
1440:            public void setLayoutDirection(LayoutDirection newValue) {
1441:                LayoutDirection oldValue = layoutDirection;
1442:                layoutDirection = newValue;
1443:                firePropertyChange(LAYOUT_DIRECTION_CHANGED_PROPERTY, oldValue,
1444:                        newValue);
1445:            }
1446:
1447:            /**
1448:             * Sets the locale of the <code>Component</code>.
1449:             *
1450:             * @param newValue the new locale
1451:             * @see #getLocale()
1452:             */
1453:            public void setLocale(Locale newValue) {
1454:                Locale oldValue = locale;
1455:                locale = newValue;
1456:                firePropertyChange(LOCALE_CHANGED_PROPERTY, oldValue, newValue);
1457:            }
1458:
1459:            /**
1460:             * Sets a generic property of the <code>Component</code>.
1461:             * The value will be stored in this <code>Component</code>'s local style.
1462:             * 
1463:             * @param propertyName the name of the property
1464:             * @param newValue the value of the property
1465:             * @see #getProperty(java.lang.String)
1466:             */
1467:            public void setProperty(String propertyName, Object newValue) {
1468:                Object oldValue = localStyle.getProperty(propertyName);
1469:                localStyle.setProperty(propertyName, newValue);
1470:                firePropertyChange(propertyName, oldValue, newValue);
1471:            }
1472:
1473:            /**
1474:             * Sets a custom render identifier for this <code>Component</code>.
1475:             * The identifier may be changed without notification if another 
1476:             * component is already using it.
1477:             * Identifiers are limited to ASCII alphanumeric values.  
1478:             * The first character must be an upper- or lower-case ASCII letter.
1479:             * Underscores and other punctuation characters are not permitted.
1480:             * Use of "TitleCase" or "camelCase" is recommended.
1481:             * 
1482:             * @param renderId the new identifier
1483:             */
1484:            public void setRenderId(String renderId) {
1485:                if (this .renderId != null && renderId != null
1486:                        && this .applicationInstance != null) {
1487:                    throw new IllegalStateException(
1488:                            "Cannot set renderId while component is registered.");
1489:                }
1490:                if (renderId != null) {
1491:                    int length = renderId.length();
1492:                    if (!isLetter(renderId.charAt(0))) {
1493:                        throw new IllegalArgumentException(
1494:                                "Invalid identifier:" + renderId);
1495:                    }
1496:                    for (int i = 1; i < length; ++i) {
1497:                        if (!isLetterOrDigit(renderId.charAt(i))) {
1498:                            throw new IllegalArgumentException(
1499:                                    "Invalid identifier:" + renderId);
1500:                        }
1501:                    }
1502:
1503:                }
1504:                assignRenderId(renderId);
1505:            }
1506:
1507:            /**
1508:             * Sets the shared style of the <code>Component</code>.
1509:             * Setting the shared style will have no impact on the local stylistic
1510:             * properties of the <code>Component</code>.
1511:             * 
1512:             * @param newValue the new shared style
1513:             * @see #getStyle()
1514:             */
1515:            public void setStyle(Style newValue) {
1516:                Style oldValue = sharedStyle;
1517:                sharedStyle = newValue;
1518:                firePropertyChange(STYLE_CHANGED_PROPERTY, oldValue, newValue);
1519:            }
1520:
1521:            /**
1522:             * Sets the name of the style to use from the
1523:             * <code>ApplicationInstance</code>-defined <code>StyleSheet</code>.
1524:             * Setting the style name will have no impact on the local stylistic
1525:             * properties of the <code>Component</code>.
1526:             * 
1527:             * @param newValue the new style name
1528:             * @see #getStyleName
1529:             */
1530:            public void setStyleName(String newValue) {
1531:                String oldValue = styleName;
1532:                styleName = newValue;
1533:                firePropertyChange(STYLE_NAME_CHANGED_PROPERTY, oldValue,
1534:                        newValue);
1535:            }
1536:
1537:            /**
1538:             * Sets the visibility state of this <code>Component</code>.
1539:             * 
1540:             * @param newValue the new visibility state
1541:             * @see #isVisible()
1542:             */
1543:            public void setVisible(boolean newValue) {
1544:                boolean oldValue = (flags & FLAG_VISIBLE) != 0;
1545:                if (oldValue != newValue) {
1546:                    flags ^= FLAG_VISIBLE; // Toggle FLAG_VISIBLE bit.
1547:                    firePropertyChange(VISIBLE_CHANGED_PROPERTY, new Boolean(
1548:                            oldValue), new Boolean(newValue));
1549:                }
1550:            }
1551:
1552:            /**
1553:             * A life-cycle method invoked before the component is rendered to ensure it
1554:             * is in a valid state. Default implementation is empty. Overriding
1555:             * implementations should ensure to invoke <code>super.validate()</code>
1556:             * out of convention.
1557:             */
1558:            public void validate() {
1559:            }
1560:
1561:            /**
1562:             * Invoked by the <code>ClientUpdateManager</code> on each component in the
1563:             * hierarchy whose <code>processInput()</code> method will layer be invoked
1564:             * in the current transaction.  This method should return true if the 
1565:             * component will be capable of processing the given input in its current 
1566:             * state or false otherwise.  This method should not do any of the actual
1567:             * processing work if overridden (any actual processing should be done in
1568:             * the <code>processInput()</code> implementation).
1569:             * <p>
1570:             * The default implementation verifies that the component is visible, 
1571:             * enabled, and not "obscured" by the presence of any modal component.
1572:             * If overriding this method, your implementation should invoke
1573:             * <code>super.verifyInput()</code>.
1574:             * 
1575:             * @param inputName the name of the input
1576:             * @param inputValue the value of the input
1577:             * @return true if the input is allowed to be processed by this component
1578:             *         in its current state
1579:             */
1580:            public boolean verifyInput(String inputName, Object inputValue) {
1581:                if (applicationInstance != null
1582:                        && !applicationInstance.verifyModalContext(this )) {
1583:                    return false;
1584:                }
1585:                return isVisible() && isEnabled();
1586:            }
1587:
1588:            /**
1589:             * Determines the index of the given <code>Component</code> within the 
1590:             * <strong>visible</strong> children of this <code>Component</code>.  If the
1591:             * given <code>Component</code> is not a child, <code>-1</code> is 
1592:             * returned.
1593:             * 
1594:             * @param c the <code>Component</code> to analyze
1595:             * @return the index of the specified <code>Component</code> amongst the 
1596:             *         <strong>visible</strong> children of this <code>Component</code>
1597:             */
1598:            public final int visibleIndexOf(Component c) {
1599:                if (!c.isVisible()) {
1600:                    return -1;
1601:                }
1602:                if (children == null) {
1603:                    return -1;
1604:                }
1605:                int visibleIndex = 0;
1606:                Iterator it = children.iterator();
1607:                while (it.hasNext()) {
1608:                    Component component = (Component) it.next();
1609:                    if (!component.isVisible()) {
1610:                        continue;
1611:                    }
1612:                    if (component.equals(c)) {
1613:                        return visibleIndex;
1614:                    }
1615:                    ++visibleIndex;
1616:                }
1617:                return -1;
1618:            }
1619:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.