Source Code Cross Referenced for RADComponent.java in  » IDE-Netbeans » form » org » netbeans » modules » form » 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 
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;
0043:
0044:        import java.beans.*;
0045:        import java.util.*;
0046:        import java.lang.reflect.Method;
0047:        import org.netbeans.modules.form.RADProperty.FakePropertyDescriptor;
0048:
0049:        import org.openide.*;
0050:        import org.openide.nodes.*;
0051:        import org.openide.util.Lookup;
0052:        import org.openide.util.NbBundle;
0053:        import org.openide.util.datatransfer.NewType;
0054:
0055:        import org.netbeans.modules.form.codestructure.*;
0056:
0057:        /**
0058:         *
0059:         * @author Ian Formanek
0060:         */
0061:
0062:        public class RADComponent {
0063:
0064:            // -----------------------------------------------------------------------------
0065:            // Static variables
0066:
0067:            public static final String PROP_NAME = "variableName"; // NOI18N
0068:
0069:            static final NewType[] NO_NEW_TYPES = {};
0070:            static final RADProperty[] NO_PROPERTIES = {};
0071:            static final BindingProperty[] NO_BINDINGS = {};
0072:
0073:            // -----------------------------------------------------------------------------
0074:            // Private variables
0075:
0076:            private static int idCounter;
0077:
0078:            private String id = Integer.toString(++idCounter);
0079:
0080:            private Class<? extends Object> beanClass;
0081:            private Object beanInstance;
0082:            private BeanInfo beanInfo;
0083:            private BeanInfo fakeBeanInfo;
0084:            private String missingClassName;
0085:
0086:            protected Node.PropertySet[] propertySets;
0087:            private Node.Property[] syntheticProperties;
0088:            private RADProperty[] beanProperties1;
0089:            private RADProperty[] beanProperties2;
0090:            private BindingProperty[][] bindingProperties;
0091:            private EventProperty[] eventProperties;
0092:            private Map<Object, RADProperty[]> otherProperties;
0093:            private List actionProperties;
0094:
0095:            private RADProperty[] knownBeanProperties;
0096:            private Event[] knownEvents; // must be grouped by EventSetDescriptor
0097:
0098:            private PropertyChangeListener propertyListener;
0099:
0100:            private Map<String, Object> auxValues;
0101:            protected Map<String, Node.Property> nameToProperty;
0102:
0103:            private RADComponent parentComponent;
0104:
0105:            private FormModel formModel;
0106:            private boolean inModel;
0107:
0108:            private RADComponentNode componentNode;
0109:
0110:            private CodeExpression componentCodeExpression;
0111:
0112:            private String storedName; // component name preserved e.g. for remove undo
0113:
0114:            private boolean valid = true;
0115:
0116:            // -----------------------------------------------------------------------------
0117:            // Constructors & Initialization
0118:
0119:            /**
0120:             * Called to initialize the component with specified FormModel.
0121:             * 
0122:             * @param formModel the FormModel of the form into which this component
0123:             * will be added
0124:             * @return <code>true</code> if the model was initialized,
0125:             * <code>false</code> otherwise.
0126:             */
0127:            public boolean initialize(FormModel formModel) {
0128:                if (this .formModel == null) {
0129:                    this .formModel = formModel;
0130:
0131:                    // properties and events will be created on first request
0132:                    clearProperties();
0133:
0134:                    //            if (beanClass != null)
0135:                    //                createCodeExpression();
0136:
0137:                    return true;
0138:                } else if (this .formModel != formModel)
0139:                    throw new IllegalStateException(
0140:                            "Cannot initialize metacomponent with another form model"); // NOI18N
0141:                return false;
0142:            }
0143:
0144:            public void setParentComponent(RADComponent parentComp) {
0145:                parentComponent = parentComp;
0146:            }
0147:
0148:            /** Initializes the bean instance represented by this meta component.
0149:             * A default instance is created for the given bean class.
0150:             * The meta component is fully initialized after this method returns.
0151:             * 
0152:             * @param beanClass the bean class to be represented by this meta component
0153:             * @return initialized instance.
0154:             * @throws java.lang.Exception when the instance cannot be initialized.
0155:             */
0156:            public Object initInstance(Class<? extends Object> beanClass)
0157:                    throws Exception {
0158:                if (beanClass == null)
0159:                    throw new NullPointerException();
0160:
0161:                if (this .beanClass != beanClass && this .beanClass != null) {
0162:                    beanInfo = null;
0163:                    fakeBeanInfo = null;
0164:                    clearProperties();
0165:                }
0166:
0167:                this .beanClass = beanClass;
0168:
0169:                Object bean = createBeanInstance();
0170:                getBeanInfo(); // force BeanInfo creation here - will be needed, may fail
0171:                setBeanInstance(bean);
0172:
0173:                return beanInstance;
0174:            }
0175:
0176:            /** Sets the bean instance represented by this meta component.
0177:             * The meta component is fully initialized after this method returns.
0178:             * @param beanInstance the bean to be represented by this meta component
0179:             */
0180:            public void setInstance(Object beanInstance) {
0181:                if (this .beanClass != beanInstance.getClass()) {
0182:                    beanInfo = null;
0183:                    fakeBeanInfo = null;
0184:                }
0185:
0186:                clearProperties();
0187:
0188:                this .beanClass = beanInstance.getClass();
0189:
0190:                getBeanInfo(); // force BeanInfo creation here - will be needed, may fail
0191:                setBeanInstance(beanInstance);
0192:
0193:                // commented out: since we don't hold default instances separately, we can't
0194:                // reinstate the bean properties against the global default property values
0195:                //        getAllBeanProperties();
0196:                //        for (int i=0; i < knownBeanProperties.length; i++) {
0197:                //            try {
0198:                //                knownBeanProperties[i].reinstateProperty();
0199:                //            }
0200:                //            catch (Exception ex) {
0201:                //                ErrorManager.getDefault()
0202:                //                    .notify(ErrorManager.INFORMATIONAL, ex);
0203:                //            }
0204:                //        }
0205:            }
0206:
0207:            /** Updates the bean instance - e.g. when setting a property requires
0208:             * to create new instance of the bean.
0209:             * 
0210:             * @param beanInstance bean instance.
0211:             */
0212:            public void updateInstance(Object beanInstance) {
0213:                if (this .beanInstance != null
0214:                        && this .beanClass == beanInstance.getClass())
0215:                    setBeanInstance(beanInstance);
0216:                // should properties also be reinstated?
0217:                // formModel.fireFormChanged() ?
0218:                else
0219:                    setInstance(beanInstance);
0220:            }
0221:
0222:            /**
0223:             * Called to create the instance of the bean. This method is called if the
0224:             * initInstance method is used; using the setInstance method, the bean
0225:             * instance is set directly.
0226:             * 
0227:             * @return the instance of the bean that will be used during design time
0228:             * @throws java.lang.Exception when the instance cannot be created.
0229:             */
0230:            protected Object createBeanInstance() throws Exception {
0231:                return CreationFactory.createDefaultInstance(beanClass);
0232:            }
0233:
0234:            /** Sets directly the bean instance. Can be overriden.
0235:             * 
0236:             * @param beanInstance bean instance.
0237:             */
0238:            protected void setBeanInstance(Object beanInstance) {
0239:                if (beanClass == null) { // bean class not set yet
0240:                    beanClass = beanInstance.getClass();
0241:                    //            createCodeExpression();
0242:                }
0243:                this .beanInstance = beanInstance;
0244:            }
0245:
0246:            void setInModel(boolean in) {
0247:                if (inModel != in) {
0248:                    inModel = in;
0249:                    formModel.updateMapping(this , in);
0250:                    if (in) {
0251:                        createCodeExpression();
0252:                    } else {
0253:                        releaseCodeExpression();
0254:                        setNodeReference(null);
0255:                    }
0256:                }
0257:            }
0258:
0259:            void setNodeReference(RADComponentNode node) {
0260:                this .componentNode = node;
0261:            }
0262:
0263:            protected void createCodeExpression() {
0264:                // create expression object
0265:                if (componentCodeExpression == null) {
0266:                    CodeStructure codeStructure = formModel.getCodeStructure();
0267:                    componentCodeExpression = codeStructure
0268:                            .createExpression(FormCodeSupport
0269:                                    .createOrigin(this ));
0270:                    codeStructure.registerExpression(componentCodeExpression);
0271:                }
0272:                // make sure a variable is attached
0273:                if (formModel.getTopRADComponent() != this 
0274:                        && componentCodeExpression.getVariable() == null) {
0275:                    formModel
0276:                            .getCodeStructure()
0277:                            .createVariableForExpression(
0278:                                    componentCodeExpression,
0279:                                    0x30DF, // default type
0280:                                    (String) getAuxValue("JavaCodeGenerator_TypeParameters"), //NOI18N
0281:                                    storedName);
0282:                }
0283:            }
0284:
0285:            /*    final void removeCodeExpression() {
0286:             if (componentCodeExpression != null) {
0287:             CodeVariable var = componentCodeExpression.getVariable();
0288:             if (var != null)
0289:             storedName = var.getName();
0290:             CodeStructure.removeExpression(componentCodeExpression);
0291:             }
0292:             } */
0293:
0294:            final void releaseCodeExpression() {
0295:                if (componentCodeExpression != null) {
0296:                    CodeVariable var = componentCodeExpression.getVariable();
0297:                    if (var != null) {
0298:                        storedName = var.getName();
0299:                        formModel.getCodeStructure()
0300:                                .removeExpressionFromVariable(
0301:                                        componentCodeExpression);
0302:                    }
0303:                }
0304:            }
0305:
0306:            // -----------------------------------------------------------------------------
0307:            // Public interface
0308:
0309:            private boolean testMode = Boolean
0310:                    .getBoolean("netbeans.form.layout_test"); // NOI18N
0311:
0312:            public final String getId() {
0313:                return testMode ? getName() : id;
0314:            }
0315:
0316:            public final boolean isReadOnly() {
0317:                return formModel.isReadOnly(); //readOnly;
0318:            }
0319:
0320:            /** Provides access to the Class of the bean represented by this RADComponent
0321:             * @return the Class of the bean represented by this RADComponent
0322:             */
0323:            public final Class<? extends Object> getBeanClass() {
0324:                return beanClass;
0325:            }
0326:
0327:            public final String getMissingClassName() {
0328:                return missingClassName;
0329:            }
0330:
0331:            public final void setMissingClassName(String className) {
0332:                missingClassName = className;
0333:            }
0334:
0335:            /** Provides access to the real instance of the bean represented by this RADComponent
0336:             * @return the instance of the bean represented by this RADComponent
0337:             */
0338:            public final Object getBeanInstance() {
0339:                return beanInstance;
0340:            }
0341:
0342:            public final RADComponent getParentComponent() {
0343:                return parentComponent;
0344:            }
0345:
0346:            public final boolean isParentComponent(RADComponent comp) {
0347:                if (comp == null)
0348:                    return false;
0349:
0350:                do {
0351:                    comp = comp.getParentComponent();
0352:                    if (comp == this )
0353:                        return true;
0354:                } while (comp != null);
0355:
0356:                return false;
0357:            }
0358:
0359:            public Object cloneBeanInstance(
0360:                    Collection<RADProperty> relativeProperties) {
0361:                Object clone;
0362:                try {
0363:                    clone = createBeanInstance();
0364:                } catch (Exception ex) { // ignore, this should not fail
0365:                    org.openide.ErrorManager.getDefault().notify(
0366:                            org.openide.ErrorManager.INFORMATIONAL, ex);
0367:                    return null;
0368:                }
0369:
0370:                FormUtils.copyPropertiesToBean(getKnownBeanProperties(), clone,
0371:                        relativeProperties);
0372:                return clone;
0373:            }
0374:
0375:            /** Provides access to BeanInfo of the bean represented by this RADComponent
0376:             * @return the BeanInfo of the bean represented by this RADComponent
0377:             */
0378:            public BeanInfo getBeanInfo() {
0379:                if (beanInfo == null) {
0380:                    try {
0381:                        beanInfo = FormUtils.getBeanInfo(beanClass);
0382:                    } catch (Error err) { // Issue 74002
0383:                        org.openide.ErrorManager.getDefault().notify(
0384:                                org.openide.ErrorManager.INFORMATIONAL, err);
0385:                        beanInfo = new FakeBeanInfo();
0386:                    } catch (IntrospectionException ex) {
0387:                        org.openide.ErrorManager.getDefault().notify(
0388:                                org.openide.ErrorManager.INFORMATIONAL, ex);
0389:                        beanInfo = new FakeBeanInfo();
0390:                    }
0391:                }
0392:                if (isValid()) {
0393:                    return beanInfo;
0394:                } else {
0395:                    if (fakeBeanInfo == null) {
0396:                        fakeBeanInfo = new FakeBeanInfo();
0397:                    }
0398:                    return fakeBeanInfo;
0399:                }
0400:            }
0401:
0402:            /** This method can be used to check whether the bean represented by this
0403:             * RADComponent has hidden-state.
0404:             * @return true if the component has hidden state, false otherwise
0405:             */
0406:            public boolean hasHiddenState() {
0407:                String name = beanClass.getName();
0408:                if (name.startsWith("javax.") // NOI18N
0409:                        || name.startsWith("java.") // NOI18N
0410:                        || name.startsWith("org.openide.")) // NOI18N
0411:                    return false;
0412:
0413:                return getBeanInfo().getBeanDescriptor().getValue(
0414:                        "hidden-state") != null; // NOI18N
0415:            }
0416:
0417:            public CodeExpression getCodeExpression() {
0418:                return componentCodeExpression;
0419:            }
0420:
0421:            /** Getter for the name of the metacomponent - it maps to variable name
0422:             * declared for the instance of the component in the generated java code.
0423:             * It is a unique identification of the component within a form, but it may
0424:             * change (currently editable as "Variable Name" in code gen. properties).
0425:             * @return current value of the Name property
0426:             */
0427:            public String getName() {
0428:                if (componentCodeExpression != null) {
0429:                    CodeVariable var = componentCodeExpression.getVariable();
0430:                    if (var != null)
0431:                        return var.getName();
0432:                }
0433:                return storedName;
0434:            }
0435:
0436:            /** Setter for the name of the component - it is the name of the
0437:             * component's node and the name of the variable declared for the component
0438:             * in the generated code.
0439:             * 
0440:             * @param name new name of the component
0441:             */
0442:            public void setName(String name) {
0443:                if (!needsVariableRename(name)) {
0444:                    return;
0445:                }
0446:
0447:                String oldName = componentCodeExpression.getVariable()
0448:                        .getName();
0449:
0450:                formModel.getCodeStructure().renameVariable(oldName, name);
0451:
0452:                resourceComponentRename(oldName, name);
0453:
0454:                renameDefaultEventHandlers(oldName, name);
0455:                // [possibility of renaming default event handlers should be probably
0456:                // configurable in options]
0457:
0458:                formModel.fireSyntheticPropertyChanged(this , PROP_NAME,
0459:                        oldName, name);
0460:
0461:                if (getNodeReference() != null)
0462:                    getNodeReference().updateName();
0463:            }
0464:
0465:            /**
0466:             * Method used to push setName through refactoring instead of just setting the variable name and
0467:             * not changing it in users custom code.
0468:             * @param name the new name for the variable
0469:             */
0470:            public void rename(String name) {
0471:                if (!needsVariableRename(name)) {
0472:                    return;
0473:                }
0474:
0475:                if (!org.openide.util.Utilities.isJavaIdentifier(name)) {
0476:                    IllegalArgumentException iae = new IllegalArgumentException(
0477:                            "Invalid component name"); // NOI18N
0478:                    ErrorManager
0479:                            .getDefault()
0480:                            .annotate(
0481:                                    iae,
0482:                                    ErrorManager.USER,
0483:                                    null,
0484:                                    FormUtils
0485:                                            .getBundleString("ERR_INVALID_COMPONENT_NAME"), // NOI18N
0486:                                    null, null);
0487:                    throw iae;
0488:                }
0489:
0490:                if (formModel.getCodeStructure().isVariableNameReserved(name)) {
0491:                    IllegalArgumentException iae = new IllegalArgumentException(
0492:                            "Component name already in use: " + name); // NOI18N
0493:                    ErrorManager
0494:                            .getDefault()
0495:                            .annotate(
0496:                                    iae,
0497:                                    ErrorManager.USER,
0498:                                    null,
0499:                                    FormUtils
0500:                                            .getBundleString("ERR_COMPONENT_NAME_ALREADY_IN_USE"), // NOI18N
0501:                                    null, null);
0502:                    throw iae;
0503:                }
0504:
0505:                try {
0506:                    RADComponentRenameRefactoringSupport rf = new RADComponentRenameRefactoringSupport(
0507:                            name);
0508:                    rf.setComponent(this );
0509:                    rf.doRenameRefactoring();
0510:                } finally { // hack for robustness - if refactoring fails for whatever reason
0511:                    if (!getName().equals(name)) {
0512:                        setName(name);
0513:                    }
0514:                }
0515:            }
0516:
0517:            private boolean needsVariableRename(String name) {
0518:                if (componentCodeExpression != null) {
0519:                    CodeVariable var = componentCodeExpression.getVariable();
0520:                    return var != null && name != null
0521:                            && !name.equals(var.getName());
0522:                }
0523:                return false;
0524:            }
0525:
0526:            public void setStoredName(String name) {
0527:                storedName = name;
0528:            }
0529:
0530:            private void renameDefaultEventHandlers(String oldComponentName,
0531:                    String newComponentName) {
0532:                boolean renamed = false; // whether any handler was renamed
0533:                FormEvents formEvents = null;
0534:
0535:                Event[] events = getKnownEvents();
0536:                for (int i = 0; i < events.length; i++) {
0537:                    String[] handlers = events[i].getEventHandlers();
0538:                    for (int j = 0; j < handlers.length; j++) {
0539:                        String handlerName = handlers[j];
0540:                        int idx = handlerName.indexOf(oldComponentName);
0541:                        if (idx >= 0) {
0542:                            if (formEvents == null)
0543:                                formEvents = getFormModel().getFormEvents();
0544:                            String newHandlerName = formEvents
0545:                                    .findFreeHandlerName(handlerName.substring(
0546:                                            0, idx)
0547:                                            + newComponentName
0548:                                            + handlerName
0549:                                                    .substring(idx
0550:                                                            + oldComponentName
0551:                                                                    .length()));
0552:                            formEvents.renameEventHandler(handlerName,
0553:                                    newHandlerName);
0554:                        }
0555:                    }
0556:                }
0557:
0558:                if (renamed && getNodeReference() != null)
0559:                    getNodeReference().fireComponentPropertySetsChange();
0560:            }
0561:
0562:            /** Allows to add an auxiliary <name, value> pair, which is persistent
0563:             * in Gandalf. The current value can be obtained using
0564:             * getAuxValue(aux_property_name) method. To remove aux value for specified
0565:             * property name, use setAuxValue(name, null).
0566:             * @param key name of the aux property
0567:             * @param value new value of the aux property or null to remove it
0568:             */
0569:            public void setAuxValue(String key, Object value) {
0570:                if (auxValues == null) {
0571:                    if (value == null)
0572:                        return;
0573:                    auxValues = new TreeMap<String, Object>();
0574:                }
0575:                auxValues.put(key, value);
0576:            }
0577:
0578:            /** Allows to obtain an auxiliary value for specified aux property name.
0579:             * @param key name of the aux property
0580:             * @return null if the aux value for specified name is not set
0581:             */
0582:            public Object getAuxValue(String key) {
0583:                return auxValues != null ? auxValues.get(key) : null;
0584:            }
0585:
0586:            /** Provides access to the FormModel class which manages the form in which
0587:             * this component has been added.
0588:             * @return the FormModel which manages the form into which this component
0589:             *         has been added
0590:             */
0591:            public final FormModel getFormModel() {
0592:                return formModel;
0593:            }
0594:
0595:            public final boolean isInModel() {
0596:                return inModel;
0597:            }
0598:
0599:            /** @return the map of all component's aux value-pairs of <String, Object>
0600:             */
0601:            public Map<String, Object> getAuxValues() {
0602:                return auxValues;
0603:            }
0604:
0605:            /** Support for new types that can be created in this node.
0606:             * @return array of new type operations that are allowed
0607:             */
0608:            public NewType[] getNewTypes() {
0609:                return NO_NEW_TYPES;
0610:            }
0611:
0612:            public Node.PropertySet[] getProperties() {
0613:                if (propertySets == null) {
0614:                    List<Node.PropertySet> propSets = new ArrayList<Node.PropertySet>(
0615:                            5);
0616:                    createPropertySets(propSets);
0617:                    propertySets = new Node.PropertySet[propSets.size()];
0618:                    propSets.toArray(propertySets);
0619:                }
0620:                return propertySets;
0621:            }
0622:
0623:            public RADProperty[] getAllBeanProperties() {
0624:                if (knownBeanProperties == null) {
0625:                    createBeanProperties();
0626:                }
0627:
0628:                return knownBeanProperties;
0629:            }
0630:
0631:            public RADProperty[] getKnownBeanProperties() {
0632:                return knownBeanProperties != null ? knownBeanProperties
0633:                        : NO_PROPERTIES;
0634:            }
0635:
0636:            public Iterator<RADProperty> getBeanPropertiesIterator(
0637:                    FormProperty.Filter filter, boolean fromAll) {
0638:                return new PropertyIterator<RADProperty>(
0639:                        fromAll ? getAllBeanProperties()
0640:                                : getKnownBeanProperties(), filter);
0641:            }
0642:
0643:            public BindingProperty[] getAllBindingProperties() {
0644:                BindingProperty[][] bprop = getBindingProperties();
0645:                BindingProperty[] prop = new BindingProperty[bprop[0].length
0646:                        + bprop[1].length + bprop[2].length];
0647:                System.arraycopy(bprop[0], 0, prop, 0, bprop[0].length);
0648:                System.arraycopy(bprop[1], 0, prop, bprop[0].length,
0649:                        bprop[1].length);
0650:                System.arraycopy(bprop[2], 0, prop, bprop[0].length
0651:                        + bprop[1].length, bprop[2].length);
0652:                return prop;
0653:            }
0654:
0655:            public BindingProperty[][] getBindingProperties() {
0656:                if (bindingProperties == null) {
0657:                    createBindingProperties();
0658:                }
0659:                return bindingProperties;
0660:            }
0661:
0662:            public final BindingProperty getBindingProperty(String name) {
0663:                for (BindingProperty prop : getAllBindingProperties()) {
0664:                    if (prop.getName().equals(name))
0665:                        return prop;
0666:                }
0667:                return null;
0668:            }
0669:
0670:            BindingProperty[] getKnownBindingProperties() {
0671:                return bindingProperties != null ? getAllBindingProperties()
0672:                        : NO_BINDINGS;
0673:            }
0674:
0675:            boolean hasBindings() {
0676:                if (bindingProperties != null) {
0677:                    for (BindingProperty p : getAllBindingProperties()) {
0678:                        if (p.getValue() != null)
0679:                            return true;
0680:                    }
0681:                }
0682:                return false;
0683:            }
0684:
0685:            /** Provides access to the Node which represents this RADComponent
0686:             * @return the RADComponentNode which represents this RADComponent
0687:             */
0688:            public RADComponentNode getNodeReference() {
0689:                return componentNode;
0690:            }
0691:
0692:            // -----------------------------------------------------------------------------
0693:            // Access to component Properties
0694:
0695:            Node.Property[] getSyntheticProperties() {
0696:                if (syntheticProperties == null)
0697:                    syntheticProperties = createSyntheticProperties();
0698:                return syntheticProperties;
0699:            }
0700:
0701:            RADProperty[] getBeanProperties1() {
0702:                if (beanProperties1 == null)
0703:                    createBeanProperties();
0704:                return beanProperties1;
0705:            }
0706:
0707:            RADProperty[] getBeanProperties2() {
0708:                if (beanProperties2 == null)
0709:                    createBeanProperties();
0710:                return beanProperties2;
0711:            }
0712:
0713:            EventProperty[] getEventProperties() {
0714:                if (eventProperties == null)
0715:                    createEventProperties();
0716:                return eventProperties;
0717:            }
0718:
0719:            List getActionProperties() {
0720:                if (actionProperties == null) {
0721:                    createBeanProperties();
0722:                }
0723:                return actionProperties;
0724:            }
0725:
0726:            protected <T> T getPropertyByName(String name,
0727:                    Class<? extends T> propertyType, boolean fromAll) {
0728:                Node.Property prop = nameToProperty.get(name);
0729:                if (prop == null && fromAll) {
0730:                    if (beanProperties1 == null && !name.startsWith("$")) // NOI18N
0731:                        createBeanProperties();
0732:                    if (eventProperties == null && name.startsWith("$")) // NOI18N
0733:                        createEventProperties();
0734:
0735:                    prop = nameToProperty.get(name);
0736:                }
0737:                return prop != null
0738:                        && (propertyType == null || propertyType
0739:                                .isAssignableFrom(prop.getClass())) ? (T) prop
0740:                        : null;
0741:            }
0742:
0743:            /**
0744:             * Returns property of given name corresponding to a property or event.
0745:             * Forces creation of all property objects.
0746:             * 
0747:             * @param name name of the property.
0748:             * @return bean or event property
0749:             */
0750:            public Node.Property getPropertyByName(String name) {
0751:                return getPropertyByName(name, null, true);
0752:            }
0753:
0754:            public final RADProperty getBeanProperty(String name) {
0755:                return getPropertyByName(name, RADProperty.class, true);
0756:            }
0757:
0758:            public final Node.Property getSyntheticProperty(String name) {
0759:                for (Node.Property prop : getSyntheticProperties()) {
0760:                    if (prop.getName().equals(name))
0761:                        return prop;
0762:                }
0763:                return null;
0764:            }
0765:
0766:            public RADProperty[] getFakeBeanProperties(String[] propNames,
0767:                    Class[] propertyTypes) {
0768:                FakeBeanInfo fbi = (FakeBeanInfo) getBeanInfo();
0769:                fbi.removePropertyDescriptors();
0770:                for (int i = 0; i < propNames.length; i++) {
0771:                    fbi.addPropertyDescriptor(propNames[i], propertyTypes[i]);
0772:                }
0773:                return getBeanProperties(propNames);
0774:            }
0775:
0776:            /**
0777:             * Returns bean properties of given names. Creates the properties if not
0778:             * created yet, but does not force creation of all bean properties.
0779:             * 
0780:             * @param propNames property names.
0781:             * @return array of properties corresponding to the names; may contain
0782:             *         null if there is no property of given name
0783:             */
0784:            public RADProperty[] getBeanProperties(String[] propNames) {
0785:                RADProperty[] properties = new RADProperty[propNames.length];
0786:                PropertyDescriptor[] descriptors = null;
0787:
0788:                boolean empty = knownBeanProperties == null;
0789:                int validCount = 0;
0790:                List<RADProperty> newProps = null;
0791:                Object[] propAccessClsf = null;
0792:                Object[] propParentChildDepClsf = null;
0793:
0794:                int descIndex = 0;
0795:                for (int i = 0; i < propNames.length; i++) {
0796:                    String name = propNames[i];
0797:                    if (name == null)
0798:                        continue;
0799:
0800:                    RADProperty prop;
0801:                    if (!empty) {
0802:                        Object obj = nameToProperty.get(name);
0803:                        prop = obj instanceof  RADProperty ? (RADProperty) obj
0804:                                : null;
0805:                    } else
0806:                        prop = null;
0807:
0808:                    if (prop == null) {
0809:                        if (descriptors == null) {
0810:                            descriptors = getBeanInfo()
0811:                                    .getPropertyDescriptors();
0812:                            if (descriptors.length == 0)
0813:                                break;
0814:                        }
0815:                        int j = descIndex;
0816:                        do {
0817:                            if (descriptors[j].getName().equals(name)) {
0818:                                if (propAccessClsf == null) {
0819:                                    propAccessClsf = FormUtils
0820:                                            .getPropertiesAccessClsf(beanClass);
0821:                                    propParentChildDepClsf = FormUtils
0822:                                            .getPropertiesParentChildDepsClsf(beanClass);
0823:                                }
0824:
0825:                                prop = createBeanProperty(descriptors[j],
0826:                                        propAccessClsf, propParentChildDepClsf);
0827:
0828:                                if (!empty) {
0829:                                    if (newProps == null)
0830:                                        newProps = new ArrayList<RADProperty>();
0831:                                    newProps.add(prop);
0832:                                }
0833:                                descIndex = j + 1;
0834:                                if (descIndex == descriptors.length
0835:                                        && i + 1 < propNames.length)
0836:                                    descIndex = 0; // go again from beginning
0837:                                break;
0838:                            }
0839:                            j++;
0840:                            if (j == descriptors.length)
0841:                                j = 0;
0842:                        } while (j != descIndex);
0843:                    }
0844:                    if (prop != null) {
0845:                        properties[i] = prop;
0846:                        validCount++;
0847:                    } else { // force all properties creation, there might be more
0848:                        // properties than from BeanInfo [currently just ButtonGroup]
0849:                        properties[i] = getPropertyByName(name,
0850:                                RADProperty.class, true);
0851:                        empty = false;
0852:                        newProps = null;
0853:                    }
0854:                }
0855:
0856:                if (empty) {
0857:                    if (validCount == properties.length)
0858:                        knownBeanProperties = properties;
0859:                    else if (validCount > 0) {
0860:                        knownBeanProperties = new RADProperty[validCount];
0861:                        for (int i = 0, j = 0; i < properties.length; i++)
0862:                            if (properties[i] != null)
0863:                                knownBeanProperties[j++] = properties[i];
0864:                    }
0865:                } else if (newProps != null) { // just for consistency, should not occur
0866:                    RADProperty[] knownProps = new RADProperty[knownBeanProperties.length
0867:                            + newProps.size()];
0868:                    System.arraycopy(knownBeanProperties, 0, knownProps, 0,
0869:                            knownBeanProperties.length);
0870:                    for (int i = 0; i < newProps.size(); i++)
0871:                        knownProps[i + knownBeanProperties.length] = newProps
0872:                                .get(i);
0873:
0874:                    knownBeanProperties = knownProps;
0875:                }
0876:
0877:                return properties;
0878:            }
0879:
0880:            public Event getEvent(String name) {
0881:                Object prop = nameToProperty.get(name);
0882:                if (prop == null && eventProperties == null) {
0883:                    createEventProperties();
0884:                    prop = nameToProperty.get(name);
0885:                }
0886:                return prop instanceof  EventProperty ? ((EventProperty) prop)
0887:                        .getEvent() : null;
0888:            }
0889:
0890:            public Event[] getEvents(String[] eventNames) {
0891:                Event[] events = new Event[eventNames.length];
0892:                EventSetDescriptor[] eventSets = null;
0893:
0894:                boolean empty = knownEvents == null;
0895:                int validCount = 0;
0896:                List<Event> newEvents = null;
0897:
0898:                int setIndex = 0;
0899:                int methodIndex = 0;
0900:
0901:                for (int i = 0; i < eventNames.length; i++) {
0902:                    String name = eventNames[i];
0903:                    if (name == null)
0904:                        continue;
0905:
0906:                    boolean fullName = name.startsWith("$"); // NOI18N
0907:
0908:                    Event event;
0909:                    if (!empty) {
0910:                        Object obj = nameToProperty.get(name);
0911:                        event = obj instanceof  EventProperty ? ((EventProperty) obj)
0912:                                .getEvent()
0913:                                : null;
0914:                    } else
0915:                        event = null;
0916:
0917:                    if (event == null) {
0918:                        if (eventSets == null) {
0919:                            eventSets = getBeanInfo().getEventSetDescriptors();
0920:                            if (eventSets.length == 0)
0921:                                break;
0922:                        }
0923:                        int j = setIndex;
0924:                        do {
0925:                            Method[] methods = eventSets[j]
0926:                                    .getListenerMethods();
0927:                            if (methods.length > 0) {
0928:                                int k = methodIndex;
0929:                                do {
0930:                                    String eventFullId = FormEvents
0931:                                            .getEventIdName(methods[k]);
0932:                                    String eventId = fullName ? eventFullId
0933:                                            : methods[k].getName();
0934:                                    if (eventId.equals(name)) {
0935:                                        event = createEventProperty(
0936:                                                eventFullId, eventSets[j],
0937:                                                methods[k]).getEvent();
0938:                                        if (!empty) {
0939:                                            if (newEvents == null)
0940:                                                newEvents = new ArrayList<Event>();
0941:                                            newEvents.add(event);
0942:                                        }
0943:                                        methodIndex = k + 1;
0944:                                        break;
0945:                                    }
0946:                                    k++;
0947:                                    if (k == methods.length)
0948:                                        k = 0;
0949:                                } while (k != methodIndex);
0950:                            }
0951:
0952:                            if (event != null) {
0953:                                if (methodIndex == methods.length) {
0954:                                    methodIndex = 0;
0955:                                    setIndex = j + 1; // will continue in new set
0956:                                    if (setIndex == eventSets.length
0957:                                            && i + 1 < eventNames.length)
0958:                                        setIndex = 0; // go again from beginning
0959:                                } else
0960:                                    setIndex = j; // will continue in the same set
0961:                                break;
0962:                            }
0963:
0964:                            j++;
0965:                            if (j == eventSets.length)
0966:                                j = 0;
0967:                            methodIndex = 0;
0968:                        } while (j != setIndex);
0969:                    }
0970:                    if (event != null) {
0971:                        events[i] = event;
0972:                        validCount++;
0973:                    }
0974:                }
0975:
0976:                if (empty) {
0977:                    if (validCount == events.length)
0978:                        knownEvents = events;
0979:                    else if (validCount > 0) {
0980:                        knownEvents = new Event[validCount];
0981:                        for (int i = 0, j = 0; i < events.length; i++)
0982:                            if (events[i] != null)
0983:                                knownEvents[j++] = events[i];
0984:                    }
0985:                } else if (newEvents != null) { // just for consistency, should not occur
0986:                    Event[] known = new Event[knownEvents.length
0987:                            + newEvents.size()];
0988:                    System.arraycopy(knownEvents, 0, known, 0,
0989:                            knownEvents.length);
0990:                    for (int i = 0; i < newEvents.size(); i++)
0991:                        known[i + knownEvents.length] = newEvents.get(i);
0992:
0993:                    knownEvents = known;
0994:                }
0995:
0996:                return events;
0997:            }
0998:
0999:            /** @return all events of the component grouped by EventSetDescriptor
1000:             */
1001:            public Event[] getAllEvents() {
1002:                if (knownEvents == null || eventProperties == null) {
1003:                    if (eventProperties == null)
1004:                        createEventProperties();
1005:                    else {
1006:                        knownEvents = new Event[eventProperties.length];
1007:                        for (int i = 0; i < eventProperties.length; i++)
1008:                            knownEvents[i] = eventProperties[i].getEvent();
1009:                    }
1010:                }
1011:
1012:                return knownEvents;
1013:            }
1014:
1015:            // Note: events must be grouped by EventSetDescriptor
1016:            public Event[] getKnownEvents() {
1017:                return knownEvents != null ? knownEvents : FormEvents.NO_EVENTS;
1018:            }
1019:
1020:            // ---------
1021:            // events
1022:
1023:            Event getDefaultEvent() {
1024:                int eventIndex = getBeanInfo().getDefaultEventIndex();
1025:                if (eventIndex < getEventProperties().length && eventIndex >= 0) {
1026:                    return eventProperties[eventIndex].getEvent();
1027:                } else {
1028:                    for (int i = 0; i < eventProperties.length; i++) {
1029:                        Event e = eventProperties[i].getEvent();
1030:                        if ("actionPerformed".equals(e.getListenerMethod()
1031:                                .getName()) // NOI18N
1032:                                && !(getBeanInstance() instanceof  javax.swing.JMenu)) {
1033:                            return e;
1034:                        }
1035:                    }
1036:                }
1037:                return null;
1038:            }
1039:
1040:            void attachDefaultEvent() {
1041:                Event event = getDefaultEvent();
1042:                if (event != null) {
1043:                    getFormModel().getFormEvents().attachEvent(event, null,
1044:                            null);
1045:                }
1046:            }
1047:
1048:            // -----------------------------------------------------------------------------
1049:            // Properties
1050:
1051:            protected void clearProperties() {
1052:                if (nameToProperty != null)
1053:                    nameToProperty.clear();
1054:                else
1055:                    nameToProperty = new HashMap<String, Node.Property>();
1056:
1057:                propertySets = null;
1058:                syntheticProperties = null;
1059:                beanProperties1 = null;
1060:                beanProperties2 = null;
1061:                knownBeanProperties = null;
1062:                eventProperties = null;
1063:                knownEvents = null;
1064:            }
1065:
1066:            protected void createPropertySets(List<Node.PropertySet> propSets) {
1067:                if (beanProperties1 == null)
1068:                    createBeanProperties();
1069:
1070:                ResourceBundle bundle = FormUtils.getBundle();
1071:
1072:                Node.PropertySet ps;
1073:                propSets.add(new Node.PropertySet("properties", // NOI18N
1074:                        bundle.getString("CTL_PropertiesTab"), // NOI18N
1075:                        bundle.getString("CTL_PropertiesTabHint")) // NOI18N
1076:                        {
1077:                            public Node.Property[] getProperties() {
1078:                                return getBeanProperties1();
1079:                            }
1080:                        });
1081:
1082:                if (isValid()) {
1083:                    Iterator entries = otherProperties.entrySet().iterator();
1084:                    while (entries.hasNext()) {
1085:                        Map.Entry entry = (Map.Entry) entries.next();
1086:                        final String category = (String) entry.getKey();
1087:                        ps = new Node.PropertySet(category, category, category) {
1088:                            public Node.Property[] getProperties() {
1089:                                if (otherProperties == null) {
1090:                                    createBeanProperties();
1091:                                }
1092:                                return (Node.Property[]) otherProperties
1093:                                        .get(category);
1094:                            }
1095:                        };
1096:                        //ps.setValue("tabName", category); // NOI18N
1097:                        propSets.add(ps);
1098:                    }
1099:
1100:                    if (beanProperties2.length > 0) {
1101:                        propSets.add(new Node.PropertySet("properties2", // NOI18N
1102:                                bundle.getString("CTL_Properties2Tab"), // NOI18N
1103:                                bundle.getString("CTL_Properties2TabHint")) // NOI18N
1104:                                {
1105:                                    public Node.Property[] getProperties() {
1106:                                        return getBeanProperties2();
1107:                                    }
1108:                                });
1109:                    }
1110:
1111:                    if (getAllBindingProperties().length > 0) {
1112:                        BindingProperty[][] bprop = getBindingProperties();
1113:                        for (int i = 0; i < bprop.length; i++) {
1114:                            final int index = i;
1115:                            ps = new Node.PropertySet("binding" + i, // NOI18N
1116:                                    bundle.getString("CTL_BindingTab" + i), // NOI18N
1117:                                    bundle.getString("CTL_BindingTabHint" + i)) // NOI18N
1118:                            {
1119:                                public Node.Property[] getProperties() {
1120:                                    return getBindingProperties()[index];
1121:                                }
1122:                            };
1123:                            ps.setValue("tabName", bundle
1124:                                    .getString("CTL_BindingTab")); // NOI18N
1125:                            propSets.add(ps);
1126:                        }
1127:                    }
1128:
1129:                    ps = new Node.PropertySet("events", // NOI18N
1130:                            bundle.getString("CTL_EventsTab"), // NOI18N
1131:                            bundle.getString("CTL_EventsTabHint")) // NOI18N
1132:                    {
1133:                        public Node.Property[] getProperties() {
1134:                            return getEventProperties();
1135:                        }
1136:                    };
1137:
1138:                    ps.setValue("tabName", bundle.getString("CTL_EventsTab")); // NOI18N
1139:                    propSets.add(ps);
1140:
1141:                }
1142:
1143:                ps = new Node.PropertySet("synthetic", // NOI18N
1144:                        bundle.getString("CTL_SyntheticTab"), // NOI18N
1145:                        bundle.getString("CTL_SyntheticTabHint")) // NOI18N
1146:                {
1147:                    public Node.Property[] getProperties() {
1148:                        return getSyntheticProperties();
1149:                    }
1150:                };
1151:                ps.setValue("tabName", bundle
1152:                        .getString("CTL_SyntheticTab_Short")); // NOI18N
1153:                propSets.add(ps);
1154:            }
1155:
1156:            protected Node.Property[] createSyntheticProperties() {
1157:                CodeGenerator codeGen = FormEditor.getCodeGenerator(formModel);
1158:                return codeGen != null ? codeGen.getSyntheticProperties(this )
1159:                        : new Node.Property[0];
1160:            }
1161:
1162:            private void createBeanProperties() {
1163:                List<RADProperty> prefProps = new ArrayList<RADProperty>();
1164:                List<RADProperty> normalProps = new ArrayList<RADProperty>();
1165:                List<RADProperty> expertProps = new ArrayList<RADProperty>();
1166:                Map<Object, List<RADProperty>> otherProps = new TreeMap<Object, List<RADProperty>>();
1167:                List<RADProperty> actionProps = new LinkedList<RADProperty>();
1168:
1169:                Object[] propsCats = FormUtils.getPropertiesCategoryClsf(
1170:                        beanClass, getBeanInfo().getBeanDescriptor());
1171:                Object[] propsAccess = FormUtils
1172:                        .getPropertiesAccessClsf(beanClass);
1173:                Object[] propParentChildDepClsf = FormUtils
1174:                        .getPropertiesParentChildDepsClsf(beanClass);
1175:
1176:                PropertyDescriptor[] props = getBeanInfo()
1177:                        .getPropertyDescriptors();
1178:                for (int i = 0; i < props.length; i++) {
1179:                    PropertyDescriptor pd = props[i];
1180:                    boolean action = (pd.getValue("action") != null); // NOI18N
1181:                    Object category = pd.getValue("category"); // NOI18N
1182:                    List<RADProperty> listToAdd;
1183:
1184:                    if ((category == null) || (!(category instanceof  String))) {
1185:                        Object propCat = FormUtils.getPropertyCategory(pd,
1186:                                propsCats);
1187:                        if (propCat == FormUtils.PROP_PREFERRED)
1188:                            listToAdd = prefProps;
1189:                        else if (propCat == FormUtils.PROP_NORMAL)
1190:                            listToAdd = normalProps;
1191:                        else if (propCat == FormUtils.PROP_EXPERT)
1192:                            listToAdd = expertProps;
1193:                        else
1194:                            continue; // PROP_HIDDEN
1195:
1196:                    } else {
1197:                        listToAdd = otherProps.get(category);
1198:                        if (listToAdd == null) {
1199:                            listToAdd = new ArrayList<RADProperty>();
1200:                            otherProps.put(category, listToAdd);
1201:                        }
1202:                    }
1203:
1204:                    RADProperty prop = getPropertyByName(pd.getName(),
1205:                            RADProperty.class, false);
1206:                    if (prop == null)
1207:                        prop = createBeanProperty(pd, propsAccess,
1208:                                propParentChildDepClsf);
1209:
1210:                    if (prop != null) {
1211:                        listToAdd.add(prop);
1212:                        if ("action".equals(pd.getName())
1213:                                && (listToAdd == prefProps)
1214:                                && javax.swing.Action.class.isAssignableFrom(pd
1215:                                        .getPropertyType())) { // NOI18N
1216:                            action = true;
1217:                            prop.setValue("actionName", FormUtils
1218:                                    .getBundleString("CTL_SetAction")); // NOI18N
1219:                        }
1220:                        if (action) {
1221:                            Object actionName = pd.getValue("actionName"); // NOI18N
1222:                            if (actionName instanceof  String) {
1223:                                prop.setValue("actionName", actionName); // NOI18N
1224:                            }
1225:                            actionProps.add(prop);
1226:                        }
1227:                    }
1228:                }
1229:
1230:                changePropertiesExplicitly(prefProps, normalProps, expertProps);
1231:
1232:                int prefCount = prefProps.size();
1233:                int normalCount = normalProps.size();
1234:                int expertCount = expertProps.size();
1235:                int otherCount = 0;
1236:
1237:                if (prefCount > 0) {
1238:                    beanProperties1 = new RADProperty[prefCount];
1239:                    prefProps.toArray(beanProperties1);
1240:                    if (normalCount + expertCount > 0) {
1241:                        normalProps.addAll(expertProps);
1242:                        beanProperties2 = new RADProperty[normalCount
1243:                                + expertCount];
1244:                        normalProps.toArray(beanProperties2);
1245:                    } else
1246:                        beanProperties2 = new RADProperty[0];
1247:                } else {
1248:                    beanProperties1 = new RADProperty[normalCount];
1249:                    normalProps.toArray(beanProperties1);
1250:                    if (expertCount > 0) {
1251:                        beanProperties2 = new RADProperty[expertCount];
1252:                        expertProps.toArray(beanProperties2);
1253:                    } else
1254:                        beanProperties2 = new RADProperty[0];
1255:                }
1256:
1257:                Map<Object, RADProperty[]> otherProps2 = new TreeMap<Object, RADProperty[]>();
1258:                RADProperty[] array = new RADProperty[0];
1259:                for (Map.Entry<Object, List<RADProperty>> entry : otherProps
1260:                        .entrySet()) {
1261:                    List<RADProperty> catProps = entry.getValue();
1262:                    otherCount += catProps.size();
1263:                    otherProps2.put(entry.getKey(), catProps.toArray(array));
1264:                }
1265:                otherProperties = otherProps2;
1266:
1267:                FormUtils.reorderProperties(beanClass, beanProperties1);
1268:                FormUtils.reorderProperties(beanClass, beanProperties2);
1269:
1270:                knownBeanProperties = new RADProperty[beanProperties1.length
1271:                        + beanProperties2.length + otherCount];
1272:                System.arraycopy(beanProperties1, 0, knownBeanProperties, 0,
1273:                        beanProperties1.length);
1274:                System.arraycopy(beanProperties2, 0, knownBeanProperties,
1275:                        beanProperties1.length, beanProperties2.length);
1276:
1277:                int where = beanProperties1.length + beanProperties2.length;
1278:
1279:                for (Map.Entry<Object, RADProperty[]> entry : otherProperties
1280:                        .entrySet()) {
1281:                    RADProperty[] catProps = entry.getValue();
1282:                    System.arraycopy(catProps, 0, knownBeanProperties, where,
1283:                            catProps.length);
1284:                    where += catProps.length;
1285:                }
1286:
1287:                actionProperties = actionProps;
1288:            }
1289:
1290:            private void createBindingProperties() {
1291:                Collection<BindingDescriptor>[] props = FormEditor
1292:                        .getBindingSupport(formModel).getBindingDescriptors(
1293:                                this );
1294:                bindingProperties = new BindingProperty[props.length][];
1295:                for (int i = 0; i < props.length; i++) {
1296:                    bindingProperties[i] = new BindingProperty[props[i].size()];
1297:                    int j = 0;
1298:                    for (BindingDescriptor desc : props[i]) {
1299:                        bindingProperties[i][j++] = new BindingProperty(this ,
1300:                                desc);
1301:                    }
1302:                }
1303:            }
1304:
1305:            private void createEventProperties() {
1306:                EventSetDescriptor[] eventSets = getBeanInfo()
1307:                        .getEventSetDescriptors();
1308:
1309:                List<EventProperty> eventPropList = new ArrayList<EventProperty>(
1310:                        eventSets.length * 5);
1311:
1312:                for (int i = 0; i < eventSets.length; i++) {
1313:                    EventSetDescriptor desc = eventSets[i];
1314:                    Method[] methods = desc.getListenerMethods();
1315:                    for (int j = 0; j < methods.length; j++) {
1316:                        String eventId = FormEvents.getEventIdName(methods[j]);
1317:                        Object prop = nameToProperty.get(eventId);
1318:                        assert (prop == null)
1319:                                || (prop instanceof  EventProperty);
1320:                        EventProperty eventProp = (EventProperty) prop;
1321:                        if (eventProp == null)
1322:                            eventProp = createEventProperty(eventId, desc,
1323:                                    methods[j]);
1324:                        eventPropList.add(eventProp);
1325:                    }
1326:                }
1327:
1328:                EventProperty[] eventProps = new EventProperty[eventPropList
1329:                        .size()];
1330:                eventPropList.toArray(eventProps);
1331:
1332:                knownEvents = new Event[eventProps.length];
1333:                for (int i = 0; i < eventProps.length; i++)
1334:                    knownEvents[i] = eventProps[i].getEvent();
1335:
1336:                FormUtils.sortProperties(eventProps);
1337:                eventProperties = eventProps;
1338:            }
1339:
1340:            protected RADProperty createBeanProperty(PropertyDescriptor desc,
1341:                    Object[] propAccessClsf, Object[] propParentChildDepClsf) {
1342:                if (desc.getPropertyType() == null)
1343:                    return null;
1344:
1345:                RADProperty prop = null;
1346:                if (desc instanceof  FakePropertyDescriptor) {
1347:                    try {
1348:                        prop = new FakeRADProperty(this ,
1349:                                (FakePropertyDescriptor) desc);
1350:                    } catch (IntrospectionException ex) { // should not happen
1351:                        ex.printStackTrace();
1352:                        return null;
1353:                    }
1354:                } else {
1355:                    prop = new RADProperty(this , desc);
1356:                }
1357:
1358:                int access = FormUtils.getPropertyAccess(desc, propAccessClsf);
1359:                if (access != 0)
1360:                    prop.setAccessType(access);
1361:
1362:                String parentChildDependency = FormUtils
1363:                        .getPropertyParentChildDependency(desc,
1364:                                propParentChildDepClsf);
1365:                if (parentChildDependency != null)
1366:                    prop.setValue(parentChildDependency, Boolean.TRUE);
1367:
1368:                setPropertyListener(prop);
1369:
1370:                // prop.addPropertyChangeListener(getPropertyListener());
1371:                nameToProperty.put(desc.getName(), prop);
1372:
1373:                return prop;
1374:            }
1375:
1376:            private EventProperty createEventProperty(String eventId,
1377:                    EventSetDescriptor eventDesc, Method eventMethod) {
1378:                EventProperty prop = new EventProperty(new Event(this ,
1379:                        eventDesc, eventMethod), eventId);
1380:                nameToProperty.put(eventId, prop);
1381:                return prop;
1382:            }
1383:
1384:            /** Called to modify original bean properties obtained from BeanInfo.
1385:             * Properties may be added, removed etc. - due to specific needs.
1386:             * 
1387:             * @param prefProps preferred properties.
1388:             * @param normalProps normal properties.
1389:             * @param expertProps expert properties.
1390:             */
1391:            protected void changePropertiesExplicitly(
1392:                    List<RADProperty> prefProps, List<RADProperty> normalProps,
1393:                    List<RADProperty> expertProps) {
1394:                // hack for buttons - add fake property for ButtonGroup
1395:                if (getBeanInstance() instanceof  javax.swing.AbstractButton) {
1396:                    try {
1397:                        RADProperty prop = new ButtonGroupProperty(this );
1398:                        setPropertyListener(prop);
1399:                        //                prop.addPropertyChangeListener(getPropertyListener());
1400:                        nameToProperty.put(prop.getName(), prop);
1401:
1402:                        Object propCategory = FormUtils.getPropertyCategory(
1403:                                prop.getPropertyDescriptor(), FormUtils
1404:                                        .getPropertiesCategoryClsf(beanClass,
1405:                                                getBeanInfo()
1406:                                                        .getBeanDescriptor()));
1407:
1408:                        if (propCategory == FormUtils.PROP_PREFERRED)
1409:                            prefProps.add(prop);
1410:                        else
1411:                            normalProps.add(prop);
1412:                    } catch (IntrospectionException ex) {
1413:                    } // should not happen
1414:                } else if (getBeanInstance() instanceof  javax.swing.JTable) {
1415:                    try {
1416:                        PropertyDescriptor pd = new PropertyDescriptor(
1417:                                "rowHeight", javax.swing.JTable.class); // NOI18N
1418:                        RADProperty prop = createBeanProperty(pd, null, null);
1419:                        nameToProperty.put("rowHeight", prop); // NOI18N
1420:                        normalProps.add(prop);
1421:                    } catch (IntrospectionException ex) {
1422:                        ex.printStackTrace();
1423:                    }
1424:                }
1425:
1426:                // PENDING improve performance - keep lookup result, listen on it etc.
1427:                boolean modified = false;
1428:                Lookup.Template<PropertyModifier> template = new Lookup.Template<PropertyModifier>(
1429:                        PropertyModifier.class);
1430:                Collection<? extends PropertyModifier> modifiers = Lookup
1431:                        .getDefault().lookup(template).allInstances();
1432:                for (PropertyModifier modifier : modifiers) {
1433:                    modified |= modifier.modifyProperties(this , prefProps,
1434:                            normalProps, expertProps);
1435:                }
1436:
1437:                if (modified) {
1438:                    checkForAddedProperties(prefProps);
1439:                    checkForAddedProperties(normalProps);
1440:                    checkForAddedProperties(expertProps);
1441:                }
1442:            }
1443:
1444:            private void checkForAddedProperties(List props) {
1445:                for (Object o : props) {
1446:                    FormProperty prop = (FormProperty) o;
1447:                    String propName = prop.getName();
1448:                    if (!nameToProperty.containsKey(propName)) {
1449:                        nameToProperty.put(propName, prop);
1450:                        setPropertyListener(prop);
1451:                    }
1452:                }
1453:            }
1454:
1455:            protected PropertyChangeListener createPropertyListener() {
1456:                return new PropertyListenerConvertor();
1457:            }
1458:
1459:            public void setPropertyListener(FormProperty property) {
1460:                if (propertyListener == null)
1461:                    propertyListener = createPropertyListener();
1462:                if (propertyListener != null) {
1463:                    property.addPropertyChangeListener(propertyListener);
1464:                    if (propertyListener instanceof  FormProperty.ValueConvertor)
1465:                        property
1466:                                .addValueConvertor((FormProperty.ValueConvertor) propertyListener);
1467:                }
1468:            }
1469:
1470:            /** Listener class for listening to changes in component's properties.
1471:             */
1472:            private class PropertyListenerConvertor implements 
1473:                    PropertyChangeListener, FormProperty.ValueConvertor {
1474:                public void propertyChange(PropertyChangeEvent evt) {
1475:                    Object source = evt.getSource();
1476:                    if (!(source instanceof  FormProperty))
1477:                        return;
1478:
1479:                    FormProperty property = (FormProperty) source;
1480:                    String propName = property.getName();
1481:                    String eventName = evt.getPropertyName();
1482:
1483:                    if (FormProperty.PROP_VALUE.equals(eventName)
1484:                            || FormProperty.PROP_VALUE_AND_EDITOR
1485:                                    .equals(eventName)) { // property value has changed (or value and editor together)
1486:                        resourcePropertyChanged(evt);
1487:
1488:                        Object oldValue = evt.getOldValue();
1489:                        Object newValue = evt.getNewValue();
1490:                        formModel
1491:                                .fireComponentPropertyChanged(
1492:                                        RADComponent.this , propName, oldValue,
1493:                                        newValue);
1494:
1495:                        if (getNodeReference() != null) { // propagate the change to node
1496:                            if (FormProperty.PROP_VALUE_AND_EDITOR
1497:                                    .equals(eventName)) {
1498:                                oldValue = ((FormProperty.ValueWithEditor) oldValue)
1499:                                        .getValue();
1500:                                newValue = ((FormProperty.ValueWithEditor) newValue)
1501:                                        .getValue();
1502:                            }
1503:
1504:                            getNodeReference().firePropertyChangeHelper(
1505:                            //                                                null, null, null);
1506:                                    propName, oldValue, newValue);
1507:                        }
1508:                    } else if (FormProperty.CURRENT_EDITOR.equals(eventName)) {
1509:                        // property editor has changed - don't fire to FormModel,
1510:                        // only to component node
1511:                        if (getNodeReference() != null)
1512:                            getNodeReference().firePropertyChangeHelper(
1513:                                    propName, null, null);
1514:                    }
1515:                }
1516:
1517:                public Object convert(Object value, FormProperty property) {
1518:                    return resourcePropertyConvert(value, property);
1519:                }
1520:            }
1521:
1522:            // -----
1523:            // resources/i18n automation
1524:
1525:            Object resourcePropertyConvert(Object value, FormProperty property) {
1526:                if (isInModel() && formModel.isUndoRedoRecording()
1527:                        && property.getPropertyContext().getFormModel() != null) {
1528:                    Object resVal = ResourceSupport.makeResource(value,
1529:                            property);
1530:                    if (resVal != value)
1531:                        return resVal;
1532:                }
1533:                return value; // do nothing
1534:            }
1535:
1536:            void resourceComponentRename(String oldName, String newName) {
1537:                if (isInModel()) {
1538:                    ResourceSupport.componentRenamed(this , oldName, newName);
1539:                }
1540:            }
1541:
1542:            void resourcePropertyChanged(PropertyChangeEvent ev) {
1543:                if (isInModel() && formModel.isFormLoaded()) {
1544:                    ResourceSupport.updateStoredValue(FormProperty
1545:                            .getEnclosedValue(ev.getOldValue()), // in case it is ValueWithEditor
1546:                            FormProperty.getEnclosedValue(ev.getNewValue()), // in case it is ValueWithEditor
1547:                            (FormProperty) ev.getSource());
1548:                }
1549:            }
1550:
1551:            // ----------
1552:
1553:            private static class PropertyIterator<T extends FormProperty>
1554:                    implements  java.util.Iterator<T> {
1555:                private T[] properties;
1556:                private FormProperty.Filter filter;
1557:
1558:                private T next;
1559:                private int index;
1560:
1561:                PropertyIterator(T[] properties, FormProperty.Filter filter) {
1562:                    this .properties = properties;
1563:                    this .filter = filter;
1564:                }
1565:
1566:                public boolean hasNext() {
1567:                    if (next == null)
1568:                        next = getNextProperty();
1569:                    return next != null;
1570:                }
1571:
1572:                public T next() {
1573:                    if (next == null)
1574:                        next = getNextProperty();
1575:                    if (next != null) {
1576:                        T prop = next;
1577:                        next = null;
1578:                        return prop;
1579:                    }
1580:                    throw new NoSuchElementException();
1581:                }
1582:
1583:                public void remove() {
1584:                    throw new UnsupportedOperationException();
1585:                }
1586:
1587:                private T getNextProperty() {
1588:                    while (index < properties.length) {
1589:                        T prop = properties[index++];
1590:                        if (filter.accept(prop))
1591:                            return prop;
1592:                    }
1593:                    return null;
1594:                }
1595:            }
1596:
1597:            @Override
1598:            public String toString() {
1599:                return super .toString() + ", name: " + getName() + ", class: "
1600:                        + getBeanClass() + ", beaninfo: " + getBeanInfo()
1601:                        + ", instance: " + getBeanInstance(); // NOI18N
1602:            }
1603:
1604:            // ----------
1605:            // a reference to a metacomponent - used instead of a metacomponent, may
1606:            // become invalid when the component is removed
1607:
1608:            interface ComponentReference {
1609:                RADComponent getComponent();
1610:            }
1611:
1612:            // ------------------------------------
1613:            // some hacks for ButtonGroup "component" ...
1614:
1615:            // pseudo-property for buttons - holds ButtonGroup in which button
1616:            // is placed; kind of "reversed" property
1617:            static class ButtonGroupProperty extends RADProperty {
1618:                ButtonGroupProperty(RADComponent comp)
1619:                        throws IntrospectionException {
1620:                    super (comp, new FakePropertyDescriptor("buttonGroup", // NOI18N
1621:                            javax.swing.ButtonGroup.class));
1622:                    setAccessType(DETACHED_READ | DETACHED_WRITE);
1623:                    setShortDescription(FormUtils
1624:                            .getBundleString("HINT_ButtonGroup")); // NOI18N
1625:                }
1626:
1627:                @Override
1628:                public boolean supportsDefaultValue() {
1629:                    return true;
1630:                }
1631:
1632:                @Override
1633:                public Object getDefaultValue() {
1634:                    return null;
1635:                }
1636:
1637:                @Override
1638:                public PropertyEditor getExpliciteEditor() {
1639:                    return new ButtonGroupPropertyEditor();
1640:                }
1641:
1642:                @Override
1643:                String getWholeSetterCode(String groupName) {
1644:                    return groupName != null ? groupName + ".add("
1645:                            + getRADComponent().getName() + ");" : // NOI18N
1646:                            null;
1647:                }
1648:            }
1649:
1650:            // property editor for selecting ButtonGroup (for ButtonGroupProperty)
1651:            public static class ButtonGroupPropertyEditor extends
1652:                    ComponentChooserEditor {
1653:                public ButtonGroupPropertyEditor() {
1654:                    super ();
1655:                    setBeanTypes(new Class[] { javax.swing.ButtonGroup.class });
1656:                    setComponentCategory(NONVISUAL_COMPONENTS);
1657:                }
1658:
1659:                @Override
1660:                public String getDisplayName() {
1661:                    return NbBundle.getBundle(getClass()).getString(
1662:                            "CTL_ButtonGroupPropertyEditor_DisplayName"); // NOI18N
1663:                }
1664:            }
1665:
1666:            public void setValid(boolean valid) {
1667:                this .valid = valid;
1668:            }
1669:
1670:            protected boolean isValid() {
1671:                return valid;
1672:            }
1673:
1674:            private class FakeBeanInfo extends SimpleBeanInfo {
1675:
1676:                private List<PropertyDescriptor> propertyDescriptors = new ArrayList<PropertyDescriptor>();
1677:
1678:                @Override
1679:                public BeanDescriptor getBeanDescriptor() {
1680:                    return (beanInfo == this ) ? new BeanDescriptor(beanClass)
1681:                            : beanInfo.getBeanDescriptor();
1682:                }
1683:
1684:                @Override
1685:                public PropertyDescriptor[] getPropertyDescriptors() {
1686:                    return propertyDescriptors
1687:                            .toArray(new PropertyDescriptor[propertyDescriptors
1688:                                    .size()]);
1689:                }
1690:
1691:                @Override
1692:                public EventSetDescriptor[] getEventSetDescriptors() {
1693:                    return new EventSetDescriptor[0];
1694:                }
1695:
1696:                void addPropertyDescriptor(String propertyName,
1697:                        Class propertyClass) {
1698:                    try {
1699:                        propertyDescriptors.add(new FakePropertyDescriptor(
1700:                                propertyName, propertyClass));
1701:                    } catch (IntrospectionException ex) {
1702:                        ex.printStackTrace(); // should not happen
1703:                    }
1704:                }
1705:
1706:                void addPropertyDescriptor(PropertyDescriptor pd) {
1707:                    propertyDescriptors.add(pd);
1708:                }
1709:
1710:                void removePropertyDescriptors() {
1711:                    propertyDescriptors.clear();
1712:                }
1713:            }
1714:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.