1 19 20 package org.netbeans.modules.form; 21 22 import java.awt.*; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.util.*; 25 import javax.swing.*; 26 import javax.swing.border.Border ; 27 import org.openide.ErrorManager; 28 29 import org.netbeans.modules.form.fakepeer.FakePeerSupport; 30 31 37 38 public class CreationFactory { 39 40 private static HashMap registry; 41 42 private static boolean defaultDescriptorsCreated = false; 43 44 interface PropertyParameters { 45 46 public String getPropertyName(); 47 48 public String getJavaParametersString(FormProperty prop); 49 50 public Object [] getPropertyParametersValues(FormProperty prop); 51 52 public Class [] getPropertyParametersTypes(); 53 } 54 55 static class Property2ParametersMapper { 56 57 private final String propertyName; 58 private final Class [] propertyType = new Class [1]; 59 private PropertyParameters parameters; 60 61 Property2ParametersMapper(Class propertyClass, String propertyName) { 62 this.propertyType[0] = propertyClass; 63 this.propertyName = propertyName; 64 } 65 66 public String getPropertyName() { 67 return propertyName; 68 } 69 70 public Class [] getPropertyTypes() { 71 if(parameters!=null){ 72 return parameters.getPropertyParametersTypes(); 73 } 74 return propertyType; 75 } 76 77 public String getJavaParametersString(FormProperty prop) { 78 if(parameters!=null){ 79 return parameters.getJavaParametersString(prop); 80 } 81 return prop.getJavaInitializationString(); 82 } 83 84 public Object [] getPropertyParametersValues(FormProperty prop) { 85 if(parameters!=null){ 86 return parameters.getPropertyParametersValues(prop); 87 } 88 try{ 89 return new Object [] { prop.getRealValue() }; 90 } catch(InvocationTargetException ite) { 91 ErrorManager.getDefault().notify(ite); 92 } catch(IllegalAccessException iae){ 93 ErrorManager.getDefault().notify(iae); 94 } 95 return new Object [] {}; 96 } 97 98 public void setPropertyParameters(PropertyParameters parameters) { 99 this.parameters = parameters; 100 } 101 } 102 103 private CreationFactory() {} 104 105 108 public static CreationDescriptor getDescriptor(Class cls) { 109 CreationDescriptor cd = (CreationDescriptor) 110 getRegistry().get(cls.getName()); 111 if (cd == null && !defaultDescriptorsCreated 112 && (cls.getName().startsWith("javax.swing.") || cls.getName().startsWith("java.awt."))) { createDefaultDescriptors(); 115 cd = (CreationDescriptor)getRegistry().get(cls.getName()); 116 } 117 return cd; 118 } 119 120 public static void registerDescriptor(CreationDescriptor desc) { 121 getRegistry().put(desc.getDescribedClass().getName(), desc); 122 } 123 124 public static void unregisterDescriptor(CreationDescriptor desc) { 125 if (registry != null) 126 registry.remove(desc.getDescribedClass().getName()); 127 } 128 129 132 public static Object createDefaultInstance(final Class cls) 133 throws Exception 134 { 135 CreationDescriptor cd = getDescriptor(cls); 136 Object instance = cd != null ? 137 cd.createDefaultInstance() : 138 cls.newInstance(); 139 140 initAfterCreation(instance); 141 return instance; 142 } 143 144 public static Object createInstance(Class cls) 145 throws Exception 146 { 147 Object instance; 148 149 CreationDescriptor cd = CreationFactory.getDescriptor(cls); 150 instance = cd != null ? cd.createDefaultInstance() : 151 cls.newInstance(); 152 153 initAfterCreation(instance); 154 return instance; 155 } 156 157 public static Object createInstance(Class cls, 158 FormProperty[] props, 159 int style) 160 throws Exception 161 { 162 CreationDescriptor cd = getDescriptor(cls); 163 if (cd == null) 164 return null; 165 166 CreationDescriptor.Creator creator = cd.findBestCreator(props, style); 167 if (creator == null) 168 return null; 169 170 Object instance = creator.createInstance(props); 171 initAfterCreation(instance); 172 return instance; 173 } 174 175 public static String getJavaCreationCode(Class cls, 176 FormProperty[] props, 177 int style) { 178 CreationDescriptor cd = getDescriptor(cls); 179 if (cd != null) { 180 CreationDescriptor.Creator creator = cd.findBestCreator(props, style); 181 if (creator != null) 182 creator.getJavaCreationCode(props, null); 183 } 184 return null; 185 } 186 187 190 public static FormProperty[] getPropertiesForCreator( 191 CreationDescriptor.Creator creator, 192 FormProperty[] properties) { 193 194 String [] propNames = creator.getPropertyNames(); 195 FormProperty[] crProps = new FormProperty[propNames.length]; 196 197 for (int i=0; i < propNames.length; i++) { 198 String propName = propNames[i]; 199 for (int j=0; j < properties.length; j++) 200 if (propName.equals(properties[j].getName())) { 201 crProps[i] = properties[j]; 202 break; 203 } 204 if (crProps[i] == null) 205 return null; } 207 208 return crProps; 209 } 210 211 public static FormProperty[] getRemainingProperties( 212 CreationDescriptor.Creator creator, 213 FormProperty[] properties) { 214 215 String [] propNames = creator.getPropertyNames(); 216 FormProperty[] remProps = new FormProperty[properties.length - propNames.length]; 217 if (remProps.length == 0) return remProps; 218 219 int ii = 0; 220 for (int i=0; i < properties.length; i++) { 221 String propName = properties[i].getName(); 222 for (int j=0; j < propNames.length; j++) { 223 if (propName.equals(propNames[j])) break; 224 if (j+1 == propNames.length) { 225 if (ii > remProps.length) 226 return null; remProps[ii++] = properties[i]; 228 } 229 } 230 } 231 232 return remProps; 233 } 234 235 public static boolean containsProperty(CreationDescriptor desc, 236 String propName) 237 { 238 CreationDescriptor.Creator[] creators = desc.getCreators(); 239 if (creators == null) 240 return false; 241 242 for (int i=0; i < creators.length; i++) { 243 String [] propNames = creators[i].getPropertyNames(); 244 for (int j=0; j < propNames.length; j++) 245 if (propNames[j].equals(propName)) 246 return true; 247 } 248 return false; 249 } 250 251 public static boolean containsProperty(CreationDescriptor.Creator creator, 252 String propName) 253 { 254 String [] propNames = creator.getPropertyNames(); 255 for (int j=0; j < propNames.length; j++) 256 if (propNames[j].equals(propName)) 257 return true; 258 return false; 259 } 260 261 public static FormProperty findProperty(String propName, 262 FormProperty[] properties) { 263 for (int i=0; i < properties.length; i++) 264 if (properties[i].getName().equals(propName)) 265 return properties[i]; 266 return null; 267 } 268 269 public static CreationDescriptor.Creator findCreator( 270 CreationDescriptor desc, 271 Class [] paramTypes) 272 { 273 CreationDescriptor.Creator[] creators = desc.getCreators(); 274 for (int i=0; i < creators.length; i++) { 275 CreationDescriptor.Creator cr = creators[i]; 276 if (cr.getParameterCount() == paramTypes.length) { 277 Class [] types = cr.getParameterTypes(); 278 boolean match = true; 279 for (int j=0; j < types.length; j++) 280 if (!types[j].isAssignableFrom(paramTypes[j])) { 281 match = false; 282 break; 283 } 284 if (match) 285 return cr; 286 } 287 } 288 return null; 289 } 290 291 295 public static int[] evaluateCreators(CreationDescriptor.Creator[] creators, 296 FormProperty[] properties, 297 boolean changedOnly) { 298 299 if (creators == null || creators.length == 0) return null; 300 301 int[] placed = new int[creators.length]; 302 for (int i=0; i < properties.length; i++) { 303 if (!changedOnly || properties[i].isChanged()) { 304 String name = properties[i].getName(); 305 306 for (int j=0; j < creators.length; j++) { 307 String [] crNames = creators[j].getPropertyNames(); 308 for (int k=0; k < crNames.length; k++) 309 if (name.equals(crNames[k])) 310 placed[j]++; 311 } 312 } 313 } 314 return placed; 315 } 316 317 321 public static int getBestCreator(CreationDescriptor.Creator[] creators, 322 FormProperty[] properties, 323 int[] placed, 324 boolean placeAllProps) 325 { 326 if (creators == null || creators.length == 0) 327 return -1; 328 329 int best = 0; 330 int[] sizes = new int[creators.length]; 331 sizes[0] = creators[0].getParameterCount(); 332 333 if (placeAllProps) { 334 for (int i=1; i < placed.length; i++) { 336 sizes[i] = creators[i].getParameterCount(); 337 if (placed[i] > placed[best] 338 || (placed[i] == placed[best] 339 && (sizes[i] < sizes[best] 340 || (sizes[i] == sizes[best] 341 && compareCreatorsAmbiguity( 342 creators[i], creators[best], properties) 343 == 1)))) 344 best = i; 345 } 346 } 347 else { for (int i=1; i < placed.length; i++) { 349 sizes[i] = creators[i].getParameterCount(); 350 int iDiff = sizes[i] - placed[i]; 351 int bestDiff = sizes[best] - placed[best]; 352 if (iDiff < bestDiff 353 || (iDiff == bestDiff 354 && (sizes[i] > sizes[best] 355 || (sizes[i] == sizes[best] 356 && compareCreatorsAmbiguity( 357 creators[i], creators[best], properties) 358 == 1)))) 359 best = i; 360 } 361 } 362 363 return best; 364 } 365 366 369 376 static int compareCreatorsAmbiguity(CreationDescriptor.Creator cr1, 377 CreationDescriptor.Creator cr2, 378 FormProperty[] properties) 379 { 380 int nullValues1 = 0; 381 int nullValues2 = 0; 382 383 for (int i=0, n=cr1.getParameterCount(); i < n; i++) { 384 String name1 = cr1.getPropertyNames()[i]; 385 String name2 = cr2.getPropertyNames()[i]; 386 if (!name1.equals(name2)) { 387 FormProperty prop1 = null; 388 FormProperty prop2 = null; 389 for (int j=0; j < properties.length; j++) 390 if (prop1 == null && name1.equals(properties[j].getName())) { 391 prop1 = properties[j]; 392 if (prop2 != null) 393 break; 394 } 395 else if (prop2 == null && name2.equals(properties[j].getName())) { 396 prop2 = properties[j]; 397 if (prop1 != null) 398 break; 399 } 400 401 if (prop1 != null && !prop1.getValueType().isPrimitive()) { 402 try { 403 if (prop1.getRealValue() == null) 404 nullValues1++; 405 } 406 catch (Exception ex) {} } 408 if (prop2 != null && !prop2.getValueType().isPrimitive()) { 409 try { 410 if (prop2.getRealValue() == null) 411 nullValues2++; 412 } 413 catch (Exception ex) {} } 415 } 416 } 417 418 if (nullValues1 == nullValues2) 419 return 0; 420 return nullValues1 < nullValues2 ? 1 : 2; 421 } 422 423 static HashMap getRegistry() { 424 if (registry == null) 425 registry = new HashMap(40); 426 return registry; 427 } 428 429 private static void initAfterCreation(Object instance) { 432 if (instance instanceof javax.swing.border.TitledBorder ) 433 ((javax.swing.border.TitledBorder )instance) 434 .setTitleFont(UIManager.getFont("TitledBorder.createDefaultInstancefont")); else if (instance instanceof java.awt.Component 436 && !(instance instanceof javax.swing.JComponent ) 437 && !(instance instanceof javax.swing.RootPaneContainer )) 438 { 439 ((Component)instance).setName(null); 440 ((Component)instance).setFont(FakePeerSupport.getDefaultAWTFont()); 441 } 442 else if (instance instanceof MenuComponent) { 443 ((MenuComponent)instance).setName(null); 444 ((MenuComponent)instance).setFont(FakePeerSupport.getDefaultAWTFont()); 445 } 446 } 447 448 private static void createDefaultDescriptors() { 451 Class [][] constrParamTypes; 452 String [][] constrPropertyNames; 453 Object [] defaultConstrParams; 454 String methodName; 455 CreationDescriptor cd; 456 InsetsPropertyParameters[] insetsPropertyParameters = 457 new InsetsPropertyParameters[] { new InsetsPropertyParameters("borderInsets") }; 458 459 try { 460 462 constrParamTypes = new Class [][] { 464 { Color.class, Integer.TYPE , Boolean.TYPE } 465 466 }; 467 constrPropertyNames = new String [][] { 468 { "lineColor", "thickness" , "roundedCorners" } 469 }; 470 471 defaultConstrParams = new Object [] { java.awt.Color.black }; 472 cd = new CreationDescriptor(); 473 cd.addConstructorCreators( 474 javax.swing.border.LineBorder .class, 475 constrParamTypes, constrPropertyNames, defaultConstrParams); 476 477 constrParamTypes = new Class [][] { 478 { Color.class }, 479 { Color.class, Integer.TYPE } 480 }; 481 constrPropertyNames = new String [][] { 482 { "lineColor" }, 483 { "lineColor", "thickness" } 484 485 }; 486 methodName = "createLineBorder"; 487 488 cd.addMethodCreators( 489 javax.swing.BorderFactory .class, javax.swing.border.LineBorder .class, methodName, 490 constrParamTypes, constrPropertyNames, null, defaultConstrParams); 491 registerDescriptor(cd); 492 493 494 defaultConstrParams = new Object [] { }; 496 constrParamTypes = new Class [][] { 497 { }, 498 { Color.class, Color.class }, 499 { Integer.TYPE }, 500 { Integer.TYPE, Color.class, Color.class } 501 }; 502 constrPropertyNames = new String [][] { 503 { }, 504 { "highlightColor", "shadowColor" }, 505 { "etchType" }, 506 { "etchType", "highlightColor", "shadowColor" } 507 }; 508 509 methodName = "createEtchedBorder"; 510 registerDescriptor(new CreationDescriptor( 511 javax.swing.BorderFactory .class, javax.swing.border.EtchedBorder .class, methodName, 512 constrParamTypes, constrPropertyNames, null, defaultConstrParams)); 513 514 constrParamTypes = new Class [][] { 516 { Insets.class } 517 }; 518 constrPropertyNames = new String [][] { 519 { "borderInsets" } 520 }; 521 522 defaultConstrParams = new Object [] { new Integer (1), new Integer (1), new Integer (1), new Integer (1) }; 523 methodName = "createEmptyBorder"; 524 525 registerDescriptor(new CreationDescriptor( 526 javax.swing.BorderFactory .class, javax.swing.border.EmptyBorder .class, 527 methodName, constrParamTypes, constrPropertyNames, insetsPropertyParameters, defaultConstrParams)); 528 529 constrParamTypes = new Class [][] { 531 { String .class }, 532 { Border .class, String .class }, 533 { Border .class, String .class, Integer.TYPE, Integer.TYPE }, 534 { Border .class, String .class, Integer.TYPE, Integer.TYPE, Font.class }, 535 { Border .class, String .class, Integer.TYPE, Integer.TYPE, Font.class, Color.class }, 536 { Border .class } 537 }; 538 constrPropertyNames = new String [][] { 539 { "title" }, 540 { "border", "title" }, 541 { "border", "title", "titleJustification", "titlePosition" }, 542 { "border", "title", "titleJustification", "titlePosition", "titleFont" }, 543 { "border", "title", "titleJustification", "titlePosition", "titleFont", "titleColor" }, 544 { "border" } 545 }; 546 547 defaultConstrParams = new Object [] { null, "", new Integer (0), new Integer (0) }; 548 methodName = "createTitledBorder"; 549 registerDescriptor(new CreationDescriptor( 550 javax.swing.BorderFactory .class, javax.swing.border.TitledBorder .class, methodName, 551 constrParamTypes, constrPropertyNames, null, defaultConstrParams)); 552 553 constrParamTypes = new Class [][] { 555 { }, 556 { Border .class, Border .class } 557 }; 558 constrPropertyNames = new String [][] { 559 { }, 560 { "outsideBorder", "insideBorder" } 561 }; 562 563 defaultConstrParams = new Object [0]; 564 methodName = "createCompoundBorder"; 565 registerDescriptor(new CreationDescriptor( 566 javax.swing.BorderFactory .class, javax.swing.border.CompoundBorder .class, methodName, 567 constrParamTypes, constrPropertyNames, null, defaultConstrParams)); 568 569 constrParamTypes = new Class [][] { 571 { Integer.TYPE }, 572 { Integer.TYPE, Color.class, Color.class }, 573 { Integer.TYPE, Color.class, Color.class, Color.class, Color.class } 574 }; 575 constrPropertyNames = new String [][] { 576 { "bevelType" }, 577 { "bevelType", "highlightOuterColor", "shadowOuterColor" }, 578 { "bevelType", "highlightOuterColor", "highlightInnerColor", 579 "shadowOuterColor", "shadowInnerColor" } 580 }; 581 582 defaultConstrParams = new Object [] { new Integer (javax.swing.border.BevelBorder.RAISED) }; 583 methodName = "createBevelBorder"; 584 registerDescriptor(new CreationDescriptor( 585 javax.swing.BorderFactory .class, javax.swing.border.BevelBorder .class, methodName, 586 constrParamTypes, constrPropertyNames, null, defaultConstrParams)); 587 588 constrParamTypes = new Class [][] { 590 { Integer.TYPE }, 591 { Integer.TYPE, Color.class, Color.class }, 592 { Integer.TYPE, Color.class, Color.class, Color.class, Color.class } 593 }; 594 constrPropertyNames = new String [][] { 595 { "bevelType" }, 596 { "bevelType", "highlightOuterColor", "shadowOuterColor" }, 597 { "bevelType", "highlightOuterColor", "highlightInnerColor", 598 "shadowOuterColor", "shadowInnerColor" } 599 }; 600 registerDescriptor(new CreationDescriptor( 601 javax.swing.border.SoftBevelBorder .class, 602 constrParamTypes, constrPropertyNames, defaultConstrParams)); 603 604 cd = new CreationDescriptor(); 606 607 constrParamTypes = new Class [][] { 608 { Icon.class } 609 }; 610 constrPropertyNames = new String [][] { 611 { "tileIcon" } 612 }; 613 cd.addConstructorCreators( javax.swing.border.MatteBorder .class, 614 constrParamTypes, constrPropertyNames, defaultConstrParams); 615 616 constrParamTypes = new Class [][] { 617 { Insets.class, Icon.class }, 618 { Insets.class, Color.class } 619 }; 620 constrPropertyNames = new String [][] { 621 { "borderInsets", "tileIcon" }, 622 { "borderInsets", "matteColor" } 623 }; 624 defaultConstrParams = new Object [] { 625 new Integer (1), new Integer (1), new Integer (1), new Integer (1), 626 java.awt.Color.black 627 }; 628 methodName = "createMatteBorder"; 629 cd.addMethodCreators(javax.swing.BorderFactory .class, javax.swing.border.MatteBorder .class, methodName, 630 constrParamTypes, constrPropertyNames, insetsPropertyParameters, defaultConstrParams); 631 registerDescriptor(cd); 632 633 635 constrParamTypes = new Class [][] { 637 { }, 638 { Integer.TYPE, Integer.TYPE } 639 }; 640 constrPropertyNames = new String [][] { 641 { }, 642 { "hgap", "vgap" } 643 }; 644 defaultConstrParams = new Object [0]; 645 registerDescriptor(new CreationDescriptor( 646 java.awt.BorderLayout .class, 647 constrParamTypes, constrPropertyNames, defaultConstrParams)); 648 649 constrParamTypes = new Class [][] { 651 { }, 652 { Integer.TYPE }, 653 { Integer.TYPE, Integer.TYPE, Integer.TYPE } 654 }; 655 constrPropertyNames = new String [][] { 656 { }, 657 { "alignment" }, 658 { "alignment", "hgap", "vgap" }, 659 }; 660 registerDescriptor(new CreationDescriptor( 661 java.awt.FlowLayout .class, 662 constrParamTypes, constrPropertyNames, defaultConstrParams)); 663 664 constrParamTypes = new Class [][] { 666 { } 667 }; 668 constrPropertyNames = new String [][] { 669 { } 670 }; 671 registerDescriptor(new CreationDescriptor( 672 java.awt.GridBagLayout .class, 673 constrParamTypes, constrPropertyNames, defaultConstrParams)); 674 675 constrParamTypes = new Class [][] { 677 { }, 678 { Integer.TYPE, Integer.TYPE }, 679 { Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE } 680 }; 681 constrPropertyNames = new String [][] { 682 { }, 683 { "rows", "columns" }, 684 { "rows", "columns", "hgap", "vgap" } 685 }; 686 registerDescriptor(new CreationDescriptor( 687 java.awt.GridLayout .class, 688 constrParamTypes, constrPropertyNames, defaultConstrParams)); 689 690 constrParamTypes = new Class [][] { 692 { }, 693 { Integer.TYPE, Integer.TYPE } 694 }; 695 constrPropertyNames = new String [][] { 696 { }, 697 { "hgap", "vgap" } 698 }; 699 registerDescriptor(new CreationDescriptor( 700 java.awt.CardLayout .class, 701 constrParamTypes, constrPropertyNames, defaultConstrParams)); 702 703 705 constrParamTypes = new Class [][] { 707 { java.awt.Frame .class }, 708 }; 709 constrPropertyNames = new String [][] { 710 { "owner" }, 711 }; 712 defaultConstrParams = new Object [] { new java.awt.Frame () }; 713 registerDescriptor(new CreationDescriptor( 714 java.awt.Dialog .class, 715 constrParamTypes, constrPropertyNames, defaultConstrParams)); 716 717 719 registerDescriptor( 722 new CreationDescriptor(javax.swing.JPanel .class) { 723 public Object createDefaultInstance() { 724 return new javax.swing.JPanel (new java.awt.FlowLayout ()); 725 } 726 } 727 ); 728 729 731 defaultDescriptorsCreated = true; 732 733 } 734 catch (NoSuchMethodException ex) { ex.printStackTrace(); 736 } 737 } 738 739 static class InsetsPropertyParameters implements PropertyParameters { 740 741 private static Class [] parameterTypes = new Class [] {Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE}; 742 private final String propertyName; 743 744 public InsetsPropertyParameters(String propertyName) { 745 this.propertyName = propertyName; 746 } 747 748 public String getPropertyName() { 749 return propertyName; 750 } 751 752 public String getJavaParametersString(FormProperty prop) { 753 Insets insets = (Insets) getRealValue (prop); 754 if(insets != null) { 755 return insets.top + ", " + insets.left + ", " + insets.bottom + ", " + insets.right; 756 } else { 757 return ""; 758 } 759 } 760 public Object [] getPropertyParametersValues(FormProperty prop) { 761 Insets insets = (Insets) getRealValue(prop); 762 if(insets != null) { 763 return new Object [] { new Integer (insets.top), new Integer (insets.left), new Integer (insets.bottom), new Integer (insets.right)}; 764 } else { 765 return new Object [] { }; 766 } 767 } 768 769 public Class [] getPropertyParametersTypes() { 770 return parameterTypes; 771 } 772 773 private static Object getRealValue(FormProperty prop){ 774 try { 775 return prop.getRealValue(); 776 } catch(InvocationTargetException ite) { 777 ErrorManager.getDefault().notify(ite); 778 } catch(IllegalAccessException iae){ 779 ErrorManager.getDefault().notify(iae); 780 } 781 return null; 782 } 783 } 784 785 786 } 787 | Popular Tags |