1 19 20 package org.netbeans.modules.form; 21 22 import java.beans.*; 23 import java.util.*; 24 import java.lang.reflect.Method ; 25 import org.netbeans.modules.form.RADProperty.FakePropertyDescriptor; 26 27 import org.openide.*; 28 import org.openide.nodes.*; 29 import org.openide.util.NbBundle; 30 import org.openide.util.datatransfer.NewType; 31 32 import org.netbeans.modules.form.codestructure.*; 33 34 38 39 public class RADComponent { 40 41 44 public static final String PROP_NAME = "variableName"; 48 static final NewType[] NO_NEW_TYPES = {}; 49 static final RADProperty[] NO_PROPERTIES = {}; 50 51 54 private static int idCounter; 55 56 private String id = Integer.toString(++idCounter); 57 58 private Class beanClass; 59 private Object beanInstance; 60 private BeanInfo beanInfo; 61 private BeanInfo fakeBeanInfo; 62 private String missingClassName; 63 65 67 protected Node.PropertySet[] propertySets; 68 private Node.Property[] syntheticProperties; 69 private RADProperty[] beanProperties1; 70 private RADProperty[] beanProperties2; 71 private EventProperty[] eventProperties; 72 private Map otherProperties; 73 private List actionProperties; 74 75 private RADProperty[] knownBeanProperties; 76 private Event[] knownEvents; 78 private PropertyChangeListener propertyListener; 79 80 private Map auxValues; 81 protected Map nameToProperty; 82 83 private RADComponent parentComponent; 84 85 private FormModel formModel; 86 private boolean inModel; 87 88 private RADComponentNode componentNode; 89 90 private CodeExpression componentCodeExpression; 91 92 94 private String storedName; 96 private boolean valid = true; 97 100 104 public boolean initialize(FormModel formModel) { 105 if (this.formModel == null) { 106 this.formModel = formModel; 107 109 clearProperties(); 111 112 115 return true; 116 } 117 else if (this.formModel != formModel) 118 throw new IllegalStateException ( 119 "Cannot initialize metacomponent with another form model"); return false; 121 } 122 123 public void setParentComponent(RADComponent parentComp) { 124 parentComponent = parentComp; 125 } 126 127 132 public Object initInstance(Class beanClass) throws Exception { 133 if (beanClass == null) 134 throw new NullPointerException (); 135 136 if (this.beanClass != beanClass && this.beanClass != null) { 137 beanInfo = null; 138 fakeBeanInfo = null; 139 clearProperties(); 140 } 141 142 this.beanClass = beanClass; 143 144 Object bean = createBeanInstance(); 145 getBeanInfo(); setBeanInstance(bean); 147 148 return beanInstance; 149 } 150 151 155 public void setInstance(Object beanInstance) { 156 if (this.beanClass != beanInstance.getClass()){ 157 beanInfo = null; 158 fakeBeanInfo = null; 159 } 160 161 clearProperties(); 162 163 this.beanClass = beanInstance.getClass(); 164 165 getBeanInfo(); setBeanInstance(beanInstance); 167 168 getAllBeanProperties(); 169 for (int i=0; i < knownBeanProperties.length; i++) { 170 try { 171 knownBeanProperties[i].reinstateProperty(); 172 } 173 catch (Exception ex) { 174 ErrorManager.getDefault() 175 .notify(ErrorManager.INFORMATIONAL, ex); 176 } 177 } 178 } 179 180 183 public void updateInstance(Object beanInstance) { 184 if (this.beanInstance != null && this.beanClass == beanInstance.getClass()) 185 setBeanInstance(beanInstance); 186 else 189 setInstance(beanInstance); 190 } 191 192 198 protected Object createBeanInstance() throws Exception { 199 return CreationFactory.createDefaultInstance(beanClass); 201 } 202 203 205 protected void setBeanInstance(Object beanInstance) { 206 if (beanClass == null) { beanClass = beanInstance.getClass(); 208 } 210 this.beanInstance = beanInstance; 211 } 212 213 void setInModel(boolean in) { 214 if (inModel != in) { 215 inModel = in; 216 formModel.updateMapping(this, in); 217 if (in) 218 createCodeExpression(); 219 else 220 releaseCodeExpression(); 221 } 222 } 223 224 void setNodeReference(RADComponentNode node) { 225 this.componentNode = node; 226 } 227 228 protected void createCodeExpression() { 229 if (componentCodeExpression == null) { 231 CodeStructure codeStructure = formModel.getCodeStructure(); 232 componentCodeExpression = codeStructure.createExpression( 233 FormCodeSupport.createOrigin(this)); 234 codeStructure.registerExpression(componentCodeExpression); 235 } 236 if (formModel.getTopRADComponent() != this && componentCodeExpression.getVariable() == null) { 238 formModel.getCodeStructure().createVariableForExpression( 239 componentCodeExpression, 240 0x30DF, storedName); 242 } 243 } 244 245 253 254 final void releaseCodeExpression() { 255 if (componentCodeExpression != null) { 256 CodeVariable var = componentCodeExpression.getVariable(); 257 if (var != null) { 258 storedName = var.getName(); 259 formModel.getCodeStructure() 260 .removeExpressionFromVariable(componentCodeExpression); 261 } 262 } 263 } 264 265 268 private boolean testMode = Boolean.getBoolean("netbeans.form.layout_test"); 270 public final String getId() { 271 return testMode ? getName() : id; 272 } 273 274 public final boolean isReadOnly() { 275 return formModel.isReadOnly(); } 277 278 281 public final Class getBeanClass() { 282 return beanClass; 283 } 284 285 public final String getMissingClassName() { 286 return missingClassName; 287 } 288 289 public final void setMissingClassName(String className) { 290 missingClassName = className; 291 } 292 293 296 public final Object getBeanInstance() { 297 return beanInstance; 298 } 299 300 public final RADComponent getParentComponent() { 301 return parentComponent; 302 } 303 304 public final boolean isParentComponent(RADComponent comp) { 305 if (comp == null) 306 return false; 307 308 do { 309 comp = comp.getParentComponent(); 310 if (comp == this) 311 return true; 312 } 313 while (comp != null); 314 315 return false; 316 } 317 318 334 public Object cloneBeanInstance(Collection relativeProperties) { 335 Object clone; 336 try { 337 clone = createBeanInstance(); 338 } 339 catch (Exception ex) { org.openide.ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex); 341 return null; 342 } 343 344 FormUtils.copyPropertiesToBean(getKnownBeanProperties(), 345 clone, 346 relativeProperties); 347 return clone; 348 } 349 350 353 public BeanInfo getBeanInfo() { 354 if (beanInfo == null) { 355 try { 356 beanInfo = FormUtils.getBeanInfo(beanClass); 357 } catch (Error err) { org.openide.ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, err); 359 beanInfo = new FakeBeanInfo(); 360 } catch (IntrospectionException ex) { 361 org.openide.ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex); 362 beanInfo = new FakeBeanInfo(); 363 } 364 } 365 if(isValid()) { 366 return beanInfo; 367 } else { 368 if (fakeBeanInfo == null) { 369 fakeBeanInfo = new FakeBeanInfo(); 370 } 371 return fakeBeanInfo ; 372 } 373 } 374 375 379 public boolean hasHiddenState() { 380 String name = beanClass.getName(); 381 if (name.startsWith("javax.") || name.startsWith("java.") || name.startsWith("org.openide.")) return false; 385 386 return getBeanInfo().getBeanDescriptor() 387 .getValue("hidden-state") != null; } 389 390 public CodeExpression getCodeExpression() { 391 return componentCodeExpression; 392 } 393 394 400 public String getName() { 401 if (componentCodeExpression != null) { 402 CodeVariable var = componentCodeExpression.getVariable(); 403 if (var != null) 404 return var.getName(); 405 } 406 return storedName; 407 } 408 409 414 public void setName(String name) { 415 if (componentCodeExpression == null) 416 return; 417 418 CodeVariable var = componentCodeExpression.getVariable(); 419 if (var == null || name.equals(var.getName())) 420 return; 421 424 if (!org.openide.util.Utilities.isJavaIdentifier(name)) { 425 IllegalArgumentException iae = 426 new IllegalArgumentException ("Invalid component name"); ErrorManager.getDefault().annotate( 428 iae, ErrorManager.USER, null, 429 FormUtils.getBundleString("ERR_INVALID_COMPONENT_NAME"), null, null); 431 throw iae; 432 } 433 434 if (formModel.getCodeStructure().isVariableNameReserved(name)) { 435 IllegalArgumentException iae = 436 new IllegalArgumentException ("Component name already in use: "+name); ErrorManager.getDefault().annotate( 438 iae, ErrorManager.USER, null, 439 FormUtils.getBundleString("ERR_COMPONENT_NAME_ALREADY_IN_USE"), null, null); 441 throw iae; 442 } 443 444 i18nComponentRename(name); 446 String oldName = var.getName(); 447 448 formModel.getCodeStructure().renameVariable(oldName, name); 449 450 renameDefaultEventHandlers(oldName, name); 451 454 formModel.fireSyntheticPropertyChanged(this, PROP_NAME, 455 oldName, name); 456 457 if (getNodeReference() != null) 458 getNodeReference().updateName(); 459 } 460 461 void setStoredName(String name) { 462 storedName = name; 463 } 464 465 private void renameDefaultEventHandlers(String oldComponentName, 466 String newComponentName) 467 { 468 boolean renamed = false; FormEvents formEvents = null; 470 471 Event[] events = getKnownEvents(); 472 for (int i=0; i < events.length; i++) { 473 String [] handlers = events[i].getEventHandlers(); 474 for (int j=0; j < handlers.length; j++) { 475 String handlerName = handlers[j]; 476 int idx = handlerName.indexOf(oldComponentName); 477 if (idx >= 0) { 478 if (formEvents == null) 479 formEvents = getFormModel().getFormEvents(); 480 String newHandlerName = formEvents.findFreeHandlerName( 481 handlerName.substring(0, idx) 482 + newComponentName 483 + handlerName.substring(idx + oldComponentName.length()) 484 ); 485 formEvents.renameEventHandler(handlerName, newHandlerName); 486 } 487 } 488 } 489 490 if (renamed && getNodeReference() != null) 491 getNodeReference().fireComponentPropertySetsChange(); 492 } 493 494 531 532 539 public void setAuxValue(String key, Object value) { 540 if (auxValues == null) { 541 if (value == null) 542 return; 543 auxValues = new TreeMap(); 544 } 545 auxValues.put(key, value); 546 } 547 548 552 public Object getAuxValue(String key) { 553 return auxValues != null ? auxValues.get(key) : null; 554 } 555 556 561 public final FormModel getFormModel() { 562 return formModel; 563 } 564 565 public final boolean isInModel() { 566 return inModel; 567 } 568 569 571 public Map getAuxValues() { 572 return auxValues; 573 } 574 575 578 public NewType[] getNewTypes() { 579 return NO_NEW_TYPES; 580 } 581 582 public Node.PropertySet[] getProperties() { 583 if (propertySets == null) { 584 ArrayList propSets = new ArrayList(5); 585 createPropertySets(propSets); 586 propertySets = new Node.PropertySet[propSets.size()]; 587 propSets.toArray(propertySets); 588 } 589 return propertySets; 590 } 591 592 public RADProperty[] getAllBeanProperties() { 593 if (knownBeanProperties == null) { 594 createBeanProperties(); 595 } 596 597 return knownBeanProperties; 598 } 599 600 public RADProperty[] getKnownBeanProperties() { 601 return knownBeanProperties != null ? knownBeanProperties : NO_PROPERTIES; 602 } 603 604 public Iterator getBeanPropertiesIterator(FormProperty.Filter filter, 605 boolean fromAll) 606 { 607 return new PropertyIterator( 608 fromAll ? getAllBeanProperties() : getKnownBeanProperties(), 609 filter); 610 } 611 612 615 public RADComponentNode getNodeReference() { 616 return componentNode; 617 } 618 619 622 Node.Property[] getSyntheticProperties() { 623 if (syntheticProperties == null) 624 syntheticProperties = createSyntheticProperties(); 625 return syntheticProperties; 626 } 627 628 RADProperty[] getBeanProperties1() { 629 if (beanProperties1 == null) 630 createBeanProperties(); 631 return beanProperties1; 632 } 633 634 RADProperty[] getBeanProperties2() { 635 if (beanProperties2 == null) 636 createBeanProperties(); 637 return beanProperties2; 638 } 639 640 EventProperty[] getEventProperties() { 641 if (eventProperties == null) 642 createEventProperties(); 643 return eventProperties; 644 } 645 646 List getActionProperties() { 647 if (actionProperties == null) { 648 createBeanProperties(); 649 } 650 return actionProperties; 651 } 652 653 protected Node.Property getPropertyByName(String name, 654 Class propertyType, 655 boolean fromAll) 656 { 657 Node.Property prop = (Node.Property) nameToProperty.get(name); 658 if (prop == null && fromAll) { 659 if (beanProperties1 == null && !name.startsWith("$")) createBeanProperties(); 661 if (eventProperties == null && name.startsWith("$")) createEventProperties(); 663 664 prop = (Node.Property) nameToProperty.get(name); 665 } 666 return prop != null 667 && (propertyType == null 668 || propertyType.isAssignableFrom(prop.getClass())) ? 669 prop : null; 670 } 671 672 675 public Node.Property getPropertyByName(String name) { 676 return getPropertyByName(name, null, true); 677 } 678 679 public final RADProperty getBeanProperty(String name) { 680 return (RADProperty) getPropertyByName(name, RADProperty.class, true); 681 } 682 683 final Node.Property getSyntheticProperty(String name) { 684 for (Node.Property prop : getSyntheticProperties()) { 685 if (prop.getName().equals(name)) 686 return prop; 687 } 688 return null; 689 } 690 691 public RADProperty[] getFakeBeanProperties(String [] propNames, Class [] propertyTypes) { 692 FakeBeanInfo fbi = (FakeBeanInfo) getBeanInfo(); 693 fbi.removePropertyDescriptors(); 694 for (int i = 0; i < propNames.length; i++) { 695 fbi.addPropertyDescriptor(propNames[i], propertyTypes[i]); 696 } 697 return getBeanProperties(propNames); 698 } 699 700 public RADProperty[] getBeanProperties(String [] propNames) { 701 RADProperty[] properties = new RADProperty[propNames.length]; 702 PropertyDescriptor[] descriptors = null; 703 704 boolean empty = knownBeanProperties == null; 705 int validCount = 0; 706 List newProps = null; 707 Object [] propAccessClsf = null; 708 Object [] propParentChildDepClsf = null; 709 710 int descIndex = 0; 711 for (int i=0; i < propNames.length; i++) { 712 String name = propNames[i]; 713 if (name == null) 714 continue; 715 716 RADProperty prop; 717 if (!empty) { 718 Object obj = nameToProperty.get(name); 719 prop = obj instanceof RADProperty ? (RADProperty) obj : null; 720 } 721 else prop = null; 722 723 if (prop == null) { 724 if (descriptors == null) { 725 descriptors = getBeanInfo().getPropertyDescriptors(); 726 if (descriptors.length == 0) 727 break; 728 } 729 int j = descIndex; 730 do { 731 if (descriptors[j].getName().equals(name)) { 732 if (propAccessClsf == null) { 733 propAccessClsf = FormUtils.getPropertiesAccessClsf(beanClass); 734 propParentChildDepClsf = FormUtils.getPropertiesParentChildDepsClsf(beanClass); 735 } 736 737 prop = createBeanProperty(descriptors[j], propAccessClsf, propParentChildDepClsf); 738 739 if (!empty) { 740 if (newProps == null) 741 newProps = new ArrayList(); 742 newProps.add(prop); 743 } 744 descIndex = j + 1; 745 if (descIndex == descriptors.length 746 && i+1 < propNames.length) 747 descIndex = 0; break; 749 } 750 j++; 751 if (j == descriptors.length) 752 j = 0; 753 } 754 while (j != descIndex); 755 } 756 if (prop != null) { 757 properties[i] = prop; 758 validCount++; 759 } 760 else { properties[i] = (RADProperty) 763 getPropertyByName(name, RADProperty.class, true); 764 empty = false; 765 newProps = null; 766 } 767 } 768 769 if (empty) { 770 if (validCount == properties.length) 771 knownBeanProperties = properties; 772 else if (validCount > 0) { 773 knownBeanProperties = new RADProperty[validCount]; 774 for (int i=0,j=0; i < properties.length; i++) 775 if (properties[i] != null) 776 knownBeanProperties[j++] = properties[i]; 777 } 778 } 779 else if (newProps != null) { RADProperty[] knownProps = 781 new RADProperty[knownBeanProperties.length + newProps.size()]; 782 System.arraycopy(knownBeanProperties, 0, 783 knownProps, 0, 784 knownBeanProperties.length); 785 for (int i=0; i < newProps.size(); i++) 786 knownProps[i + knownBeanProperties.length] = (RADProperty) 787 newProps.get(i); 788 789 knownBeanProperties = knownProps; 790 } 791 792 return properties; 793 } 794 795 public Event getEvent(String name) { 796 Object prop = nameToProperty.get(name); 797 if (prop == null && eventProperties == null) { 798 createEventProperties(); 799 prop = nameToProperty.get(name); 800 } 801 return prop instanceof EventProperty ? 802 ((EventProperty)prop).getEvent() : null; 803 } 804 805 public Event[] getEvents(String [] eventNames) { 806 Event[] events = new Event[eventNames.length]; 807 EventSetDescriptor[] eventSets = null; 808 809 boolean empty = knownEvents == null; 810 int validCount = 0; 811 List newEvents = null; 812 813 int setIndex = 0; 814 int methodIndex = 0; 815 816 for (int i=0; i < eventNames.length; i++) { 817 String name = eventNames[i]; 818 if (name == null) 819 continue; 820 821 boolean fullName = name.startsWith("$"); 823 Event event; 824 if (!empty) { 825 Object obj = nameToProperty.get(name); 826 event = obj instanceof EventProperty ? 827 ((EventProperty)obj).getEvent() : null; 828 } 829 else event = null; 830 831 if (event == null) { 832 if (eventSets == null) { 833 eventSets = getBeanInfo().getEventSetDescriptors(); 834 if (eventSets.length == 0) 835 break; 836 } 837 int j = setIndex; 838 do { 839 Method [] methods = eventSets[j].getListenerMethods(); 840 if (methods.length > 0) { 841 int k = methodIndex; 842 do { 843 String eventFullId = 844 FormEvents.getEventIdName(methods[k]); 845 String eventId = fullName ? 846 eventFullId : methods[k].getName(); 847 if (eventId.equals(name)) { 848 event = createEventProperty(eventFullId, 849 eventSets[j], 850 methods[k]) 851 .getEvent(); 852 if (!empty) { 853 if (newEvents == null) 854 newEvents = new ArrayList(); 855 newEvents.add(event); 856 } 857 methodIndex = k + 1; 858 break; 859 } 860 k++; 861 if (k == methods.length) 862 k = 0; 863 } 864 while (k != methodIndex); 865 } 866 867 if (event != null) { 868 if (methodIndex == methods.length) { 869 methodIndex = 0; 870 setIndex = j + 1; if (setIndex == eventSets.length 872 && i+1 < eventNames.length) 873 setIndex = 0; } 875 else setIndex = j; break; 877 } 878 879 j++; 880 if (j == eventSets.length) 881 j = 0; 882 methodIndex = 0; 883 } 884 while (j != setIndex); 885 } 886 if (event != null) { 887 events[i] = event; 888 validCount++; 889 } 890 } 891 892 if (empty) { 893 if (validCount == events.length) 894 knownEvents = events; 895 else if (validCount > 0) { 896 knownEvents = new Event[validCount]; 897 for (int i=0,j=0; i < events.length; i++) 898 if (events[i] != null) 899 knownEvents[j++] = events[i]; 900 } 901 } 902 else if (newEvents != null) { Event[] known = new Event[knownEvents.length + newEvents.size()]; 904 System.arraycopy(knownEvents, 0, known, 0, knownEvents.length); 905 for (int i=0; i < newEvents.size(); i++) 906 known[i + knownEvents.length] = (Event) newEvents.get(i); 907 908 knownEvents = known; 909 } 910 911 return events; 912 } 913 914 916 public Event[] getAllEvents() { 917 if (knownEvents == null || eventProperties == null) { 918 if (eventProperties == null) 919 createEventProperties(); 920 else { 921 knownEvents = new Event[eventProperties.length]; 922 for (int i=0; i < eventProperties.length; i++) 923 knownEvents[i] = eventProperties[i].getEvent(); 924 } 925 } 926 927 return knownEvents; 928 } 929 930 public Event[] getKnownEvents() { 932 return knownEvents != null ? knownEvents : FormEvents.NO_EVENTS; 933 } 934 935 938 void attachDefaultEvent() { 939 Event event = null; 940 941 int eventIndex = getBeanInfo().getDefaultEventIndex(); 942 if (eventIndex < getEventProperties().length && eventIndex >= 0) 943 event = eventProperties[eventIndex].getEvent(); 944 else 945 for (int i=0; i < eventProperties.length; i++) { 946 Event e = eventProperties[i].getEvent(); 947 if ("actionPerformed".equals(e.getListenerMethod().getName())) { event = e; 949 break; 950 } 951 } 952 953 if (event != null) 954 getFormModel().getFormEvents().attachEvent(event, null, null); 955 } 956 957 960 protected void clearProperties() { 961 if (nameToProperty != null) 962 nameToProperty.clear(); 963 else nameToProperty = new HashMap(); 964 965 propertySets = null; 966 syntheticProperties = null; 967 beanProperties1 = null; 968 beanProperties2 = null; 969 knownBeanProperties = null; 970 eventProperties = null; 971 knownEvents = null; 972 } 973 974 protected void createPropertySets(List propSets) { 975 if (beanProperties1 == null) 976 createBeanProperties(); 977 978 ResourceBundle bundle = FormUtils.getBundle(); 979 980 Node.PropertySet ps; 981 propSets.add(new Node.PropertySet( 982 "properties", bundle.getString("CTL_PropertiesTab"), bundle.getString("CTL_PropertiesTabHint")) { 986 public Node.Property[] getProperties() { 987 return getBeanProperties1(); 988 } 989 }); 990 991 if(isValid()) { 992 Iterator entries = otherProperties.entrySet().iterator(); 993 while (entries.hasNext()) { 994 Map.Entry entry = (Map.Entry)entries.next(); 995 final String category = (String )entry.getKey(); 996 ps = new Node.PropertySet(category, category, category) { 997 public Node.Property[] getProperties() { 998 if (otherProperties == null) { 999 createBeanProperties(); 1000 } 1001 return (Node.Property[])otherProperties.get(category); 1002 } 1003 }; 1004 propSets.add(ps); 1006 } 1007 1008 if (beanProperties2.length > 0) 1009 propSets.add(new Node.PropertySet( 1010 "properties2", bundle.getString("CTL_Properties2Tab"), bundle.getString("CTL_Properties2TabHint")) { 1014 public Node.Property[] getProperties() { 1015 return getBeanProperties2(); 1016 } 1017 }); 1018 1019 ps = new Node.PropertySet( 1020 "events", bundle.getString("CTL_EventsTab"), bundle.getString("CTL_EventsTabHint")) { 1024 public Node.Property[] getProperties() { 1025 return getEventProperties(); 1026 } 1027 }; 1028 1029 ps.setValue("tabName", bundle.getString("CTL_EventsTab")); propSets.add(ps); 1031 1032 } 1033 1034 ps = new Node.PropertySet( 1035 "synthetic", bundle.getString("CTL_SyntheticTab"), bundle.getString("CTL_SyntheticTabHint")) { 1039 public Node.Property[] getProperties() { 1040 return getSyntheticProperties(); 1041 } 1042 }; 1043 ps.setValue("tabName", bundle.getString("CTL_SyntheticTab_Short")); propSets.add(ps); 1045 } 1046 1047 protected Node.Property[] createSyntheticProperties() { 1048 return FormEditor.getCodeGenerator(formModel).getSyntheticProperties(this); 1049 } 1050 1051 private void createBeanProperties() { 1052 ArrayList prefProps = new ArrayList(); 1053 ArrayList normalProps = new ArrayList(); 1054 ArrayList expertProps = new ArrayList(); 1055 Map otherProps = new TreeMap(); 1056 List actionProps = new LinkedList(); 1057 1058 Object [] propsCats = FormUtils.getPropertiesCategoryClsf( 1059 beanClass, getBeanInfo().getBeanDescriptor()); 1060 Object [] propsAccess = FormUtils.getPropertiesAccessClsf(beanClass); 1061 Object [] propParentChildDepClsf = FormUtils.getPropertiesParentChildDepsClsf(beanClass); 1062 1063 PropertyDescriptor[] props = getBeanInfo().getPropertyDescriptors(); 1064 for (int i = 0; i < props.length; i++) { 1065 PropertyDescriptor pd = props[i]; 1066 boolean action = (pd.getValue("action") != null); Object category = pd.getValue("category"); List listToAdd; 1069 1070 if ((category == null) || (!(category instanceof String ))) { 1071 Object propCat = FormUtils.getPropertyCategory(pd, propsCats); 1072 if (propCat == FormUtils.PROP_PREFERRED) 1073 listToAdd = prefProps; 1074 else if (propCat == FormUtils.PROP_NORMAL) 1075 listToAdd = normalProps; 1076 else if (propCat == FormUtils.PROP_EXPERT) 1077 listToAdd = expertProps; 1078 else continue; 1080 } else { 1081 listToAdd = (List)otherProps.get(category); 1082 if (listToAdd == null) { 1083 listToAdd = new ArrayList(); 1084 otherProps.put(category, listToAdd); 1085 } 1086 } 1087 1088 FormProperty prop = (FormProperty) nameToProperty.get(pd.getName()); 1089 if (prop == null) 1090 prop = createBeanProperty(pd, propsAccess, propParentChildDepClsf); 1091 1092 if (prop != null) { 1093 listToAdd.add(prop); 1094 if (action) { 1095 Object actionName = pd.getValue("actionName"); if (actionName instanceof String ) { 1097 prop.setValue("actionName", actionName); } 1099 actionProps.add(prop); 1100 } 1101 } 1102 } 1103 1104 changePropertiesExplicitly(prefProps, normalProps, expertProps); 1105 1106 int prefCount = prefProps.size(); 1107 int normalCount = normalProps.size(); 1108 int expertCount = expertProps.size(); 1109 int otherCount = 0; 1110 1111 if (prefCount > 0) { 1112 beanProperties1 = new RADProperty[prefCount]; 1113 prefProps.toArray(beanProperties1); 1114 if (normalCount + expertCount > 0) { 1115 normalProps.addAll(expertProps); 1116 beanProperties2 = new RADProperty[normalCount + expertCount]; 1117 normalProps.toArray(beanProperties2); 1118 } 1119 else beanProperties2 = new RADProperty[0]; 1120 } 1121 else { 1122 beanProperties1 = new RADProperty[normalCount]; 1123 normalProps.toArray(beanProperties1); 1124 if (expertCount > 0) { 1125 beanProperties2 = new RADProperty[expertCount]; 1126 expertProps.toArray(beanProperties2); 1127 } 1128 else beanProperties2 = new RADProperty[0]; 1129 } 1130 1131 Iterator entries = otherProps.entrySet().iterator(); 1132 RADProperty[] array = new RADProperty[0]; 1133 while (entries.hasNext()) { 1134 Map.Entry entry = (Map.Entry)entries.next(); 1135 ArrayList catProps = (ArrayList)entry.getValue(); 1136 otherCount += catProps.size(); 1137 entry.setValue(catProps.toArray(array)); 1138 } 1139 otherProperties = otherProps; 1140 1141 FormUtils.reorderProperties(beanClass, beanProperties1); 1142 FormUtils.reorderProperties(beanClass, beanProperties2); 1143 1144 knownBeanProperties = new RADProperty[beanProperties1.length 1145 + beanProperties2.length + otherCount]; 1146 System.arraycopy(beanProperties1, 0, 1147 knownBeanProperties, 0, 1148 beanProperties1.length); 1149 System.arraycopy(beanProperties2, 0, 1150 knownBeanProperties, beanProperties1.length, 1151 beanProperties2.length); 1152 1153 int where = beanProperties1.length + beanProperties2.length; 1154 1155 entries = otherProperties.entrySet().iterator(); 1156 while (entries.hasNext()) { 1157 Map.Entry entry = (Map.Entry)entries.next(); 1158 RADProperty[] catProps = (RADProperty[])entry.getValue(); 1159 System.arraycopy(catProps, 0, 1160 knownBeanProperties, where, 1161 catProps.length); 1162 where += catProps.length; 1163 } 1164 1165 actionProperties = actionProps; 1166 } 1167 1168 private void createEventProperties() { 1169 EventSetDescriptor[] eventSets = getBeanInfo().getEventSetDescriptors(); 1170 1171 List eventPropList = new ArrayList(eventSets.length * 5); 1172 1173 for (int i=0; i < eventSets.length; i++) { 1174 EventSetDescriptor desc = eventSets[i]; 1175 Method [] methods = desc.getListenerMethods(); 1176 for (int j=0; j < methods.length; j++) { 1177 String eventId = FormEvents.getEventIdName(methods[j]); 1178 Object prop = nameToProperty.get(eventId); 1179 if (prop == null) 1180 prop = createEventProperty(eventId, desc, methods[j]); 1181 eventPropList.add(prop); 1182 } 1183 } 1184 1185 EventProperty[] eventProps = new EventProperty[eventPropList.size()]; 1186 eventPropList.toArray(eventProps); 1187 1188 knownEvents = new Event[eventProps.length]; 1189 for (int i=0; i < eventProps.length; i++) 1190 knownEvents[i] = eventProps[i].getEvent(); 1191 1192 FormUtils.sortProperties(eventProps); 1193 eventProperties = eventProps; 1194 } 1195 1196 protected RADProperty createBeanProperty(PropertyDescriptor desc, 1197 Object [] propAccessClsf, 1198 Object [] propParentChildDepClsf) 1199 { 1200 if (desc.getPropertyType() == null) 1201 return null; 1202 1203 RADProperty prop = null; 1204 if(desc instanceof FakePropertyDescriptor){ 1205 try { 1206 prop = new FakeRADProperty(this, (FakePropertyDescriptor) desc); 1207 } catch (IntrospectionException ex) { ex.printStackTrace(); 1209 return null; 1210 } 1211 } else { 1212 prop = new RADProperty(this, desc); 1213 } 1214 1215 int access = FormUtils.getPropertyAccess(desc, propAccessClsf); 1216 if (access != 0) 1217 prop.setAccessType(access); 1218 1219 String parentChildDependency = FormUtils.getPropertyParentChildDependency( 1220 desc, propParentChildDepClsf); 1221 if (parentChildDependency != null) 1222 prop.setValue(parentChildDependency, Boolean.TRUE); 1223 1224 setPropertyListener(prop); 1225 1226 nameToProperty.put(desc.getName(), prop); 1228 1229 return prop; 1230 } 1231 1232 protected EventProperty createEventProperty(String eventId, 1233 EventSetDescriptor eventDesc, 1234 Method eventMethod) 1235 { 1236 EventProperty prop = new EventProperty(new Event(this, 1237 eventDesc, 1238 eventMethod), 1239 eventId); 1240 nameToProperty.put(eventId, prop); 1241 return prop; 1242 } 1243 1244 1247 protected void changePropertiesExplicitly(List prefProps, 1248 List normalProps, 1249 List expertProps) { 1250 if (getBeanInstance() instanceof javax.swing.AbstractButton ) 1252 try { 1253 RADProperty prop = new ButtonGroupProperty(this); 1254 setPropertyListener(prop); 1255 nameToProperty.put(prop.getName(), prop); 1257 1258 Object propCategory = FormUtils.getPropertyCategory( 1259 prop.getPropertyDescriptor(), 1260 FormUtils.getPropertiesCategoryClsf( 1261 beanClass, getBeanInfo().getBeanDescriptor())); 1262 1263 if (propCategory == FormUtils.PROP_PREFERRED) 1264 prefProps.add(prop); 1265 else normalProps.add(prop); 1266 } 1267 catch (IntrospectionException ex) {} } 1269 1270 protected PropertyChangeListener createPropertyListener() { 1271 return new PropertyListenerConvertor(); 1272 } 1273 1274 protected void setPropertyListener(FormProperty property) { 1275 if (propertyListener == null) 1276 propertyListener = createPropertyListener(); 1277 if (propertyListener != null) { 1278 property.addPropertyChangeListener(propertyListener); 1279 if (propertyListener instanceof FormProperty.ValueConvertor) 1280 property.addValueConvertor((FormProperty.ValueConvertor)propertyListener); 1281 } 1282 } 1283 1289 1291 private class PropertyListenerConvertor implements PropertyChangeListener, FormProperty.ValueConvertor { 1292 public void propertyChange(PropertyChangeEvent evt) { 1293 Object source = evt.getSource(); 1294 if (!(source instanceof FormProperty)) 1295 return; 1296 1297 FormProperty property = (FormProperty) source; 1298 String propName = property.getName(); 1299 String eventName = evt.getPropertyName(); 1300 1301 if (FormProperty.PROP_VALUE.equals(eventName) 1302 || FormProperty.PROP_VALUE_AND_EDITOR.equals(eventName)) 1303 { i18nPropertyChanged(evt); 1305 1306 Object oldValue = evt.getOldValue(); 1307 Object newValue = evt.getNewValue(); 1308 formModel.fireComponentPropertyChanged( 1309 RADComponent.this, propName, oldValue, newValue); 1310 1311 if (getNodeReference() != null) { if (FormProperty.PROP_VALUE_AND_EDITOR.equals(eventName)) { 1313 oldValue = ((FormProperty.ValueWithEditor)oldValue).getValue(); 1314 newValue = ((FormProperty.ValueWithEditor)newValue).getValue(); 1315 } 1316 1317 getNodeReference().firePropertyChangeHelper( 1318 propName, oldValue, newValue); 1320 } 1321 } 1322 else if (FormProperty.CURRENT_EDITOR.equals(eventName)) { 1323 if (getNodeReference() != null) 1326 getNodeReference().firePropertyChangeHelper( 1327 propName, null, null); 1328 } 1329 } 1330 1331 public Object convert(Object value, FormProperty property) { 1332 return i18nPropertyConvert(value, property); 1333 } 1334 } 1335 1336 1339 Object i18nPropertyConvert(Object value, FormProperty property) { 1340 if (isInModel() && formModel.isUndoRedoRecording() 1341 && property.getPropertyContext().getFormModel() != null) { 1342 Object val = FormProperty.getEnclosedValue(value); 1343 Object intVal = I18nSupport.internationalizeProperty(val, property, RADComponent.this); 1344 if (intVal != val) 1345 return intVal; 1346 } 1347 return value; } 1349 1350 void i18nComponentRename(String newName) { 1351 if (isInModel()) { 1352 I18nSupport.componentRenamed(this, newName); 1353 } 1354 } 1355 1356 void i18nPropertyChanged(PropertyChangeEvent ev) { 1357 if (isInModel() && formModel.isFormLoaded()) { 1358 I18nSupport.updateStoredValue( 1359 FormProperty.getEnclosedValue(ev.getOldValue()), FormProperty.getEnclosedValue(ev.getNewValue()), (FormProperty)ev.getSource(), 1362 RADComponent.this); 1363 } 1364 } 1365 1366 1368 private static class PropertyIterator implements java.util.Iterator { 1369 private FormProperty[] properties; 1370 private FormProperty.Filter filter; 1371 1372 private FormProperty next; 1373 private int index; 1374 1375 PropertyIterator(FormProperty[] properties, 1376 FormProperty.Filter filter) 1377 { 1378 this.properties = properties; 1379 this.filter = filter; 1380 } 1381 1382 public boolean hasNext() { 1383 if (next == null) 1384 next = getNextProperty(); 1385 return next != null; 1386 } 1387 1388 public Object next() { 1389 if (next == null) 1390 next = getNextProperty(); 1391 if (next != null) { 1392 Object prop = next; 1393 next = null; 1394 return prop; 1395 } 1396 throw new NoSuchElementException(); 1397 } 1398 1399 public void remove() { 1400 throw new UnsupportedOperationException (); 1401 } 1402 1403 private FormProperty getNextProperty() { 1404 while (index < properties.length) { 1405 FormProperty prop = properties[index++]; 1406 if (filter.accept(prop)) 1407 return prop; 1408 } 1409 return null; 1410 } 1411 } 1412 1413 1446 1447 1450 public java.lang.String toString() { 1451 return super.toString() + ", name: "+getName()+", class: "+getBeanClass()+", beaninfo: "+getBeanInfo() + ", instance: "+getBeanInstance(); } 1453 1454 public void debugChangedValues() { 1455 } 1456 1457 1461 interface ComponentReference { 1462 RADComponent getComponent(); 1463 } 1464 1465 1468 static class ButtonGroupProperty extends RADProperty { 1471 ButtonGroupProperty(RADComponent comp) throws IntrospectionException { 1472 super(comp, 1473 new FakePropertyDescriptor("buttonGroup", javax.swing.ButtonGroup .class)); 1475 setAccessType(DETACHED_READ | DETACHED_WRITE); 1476 setShortDescription(FormUtils.getBundleString("HINT_ButtonGroup")); } 1478 1479 public boolean supportsDefaultValue() { 1480 return true; 1481 } 1482 1483 public Object getDefaultValue() { 1484 return null; 1485 } 1486 1487 public PropertyEditor getExpliciteEditor() { 1488 return new ButtonGroupPropertyEditor(); 1489 } 1490 1491 String getWholeSetterCode(String groupName) { 1492 return groupName != null ? 1493 groupName + ".add(" + getRADComponent().getName() + ");" : null; 1495 } 1496 } 1497 1498 public static class ButtonGroupPropertyEditor extends ComponentChooserEditor { 1500 public ButtonGroupPropertyEditor() { 1501 super(); 1502 setBeanTypes(new Class [] { javax.swing.ButtonGroup .class }); 1503 setComponentCategory(NONVISUAL_COMPONENTS); 1504 } 1505 1506 public String getDisplayName() { 1507 return NbBundle.getBundle(getClass()).getString("CTL_ButtonGroupPropertyEditor_DisplayName"); } 1509 } 1510 1511 public void setValid(boolean valid){ 1512 this.valid = valid; 1513 } 1514 1515 protected boolean isValid() { 1516 return valid; 1517 } 1518 1519 private class FakeBeanInfo extends SimpleBeanInfo { 1520 1521 private List propertyDescriptors = new ArrayList(); 1522 1523 public BeanDescriptor getBeanDescriptor() { 1524 return (beanInfo == this) ? null : beanInfo.getBeanDescriptor(); 1525 } 1526 1527 public PropertyDescriptor[] getPropertyDescriptors() { 1528 return (PropertyDescriptor[]) propertyDescriptors.toArray( 1529 new PropertyDescriptor[propertyDescriptors.size()]); 1530 } 1531 1532 public EventSetDescriptor[] getEventSetDescriptors() { 1533 return new EventSetDescriptor[0]; 1534 } 1535 1536 void addPropertyDescriptor(String propertyName, Class propertyClass) { 1537 try { 1538 propertyDescriptors.add(new FakePropertyDescriptor(propertyName, propertyClass)); 1539 } catch (IntrospectionException ex) { 1540 ex.printStackTrace(); } 1542 } 1543 1544 void addPropertyDescriptor(PropertyDescriptor pd) { 1545 propertyDescriptors.add(pd); 1546 } 1547 1548 void removePropertyDescriptors() { 1549 propertyDescriptors.clear(); 1550 } 1551 } 1552} 1553 | Popular Tags |