1 19 20 package org.netbeans.modules.form; 21 22 import java.beans.*; 23 import java.lang.reflect.*; 24 import org.openide.nodes.Node; 25 26 55 56 public abstract class FormProperty extends Node.Property { 57 58 61 public static final String PROP_VALUE = "propertyValue"; public static final String CURRENT_EDITOR = "currentEditor"; public static final String PROP_VALUE_AND_EDITOR = "propertyValueAndEditor"; public static final String PROP_PRE_CODE = "preCode"; public static final String PROP_POST_CODE = "postCode"; 67 public static final int NORMAL_RW = 0; 75 76 public static final int DETACHED_READ = 1; public static final int DETACHED_WRITE = 2; 79 private static final int NO_READ_PROP = 4; private static final int NO_WRITE_PROP = 8; public static final int NO_READ = DETACHED_READ | NO_READ_PROP; public static final int NO_WRITE = DETACHED_WRITE | NO_WRITE_PROP; 84 85 protected int propType = NORMAL_RW; 88 89 FormPropertyContext propertyContext; 90 91 protected Object propertyValue; protected boolean valueSet = false; boolean valueChanged = false; 95 private boolean externalChangeMonitoring = true; 96 private Object lastRealValue; 98 String preCode; 99 String postCode; 100 101 FormPropertyEditor formPropertyEditor; 102 PropertyEditor currentEditor; 103 104 private PropertyChangeSupport changeSupport; 105 private VetoableChangeSupport vetoableChangeSupport; 106 private boolean fireChanges = true; 107 108 private java.util.List <ValueConvertor> convertors; 109 110 112 115 protected FormProperty(FormPropertyContext propertyContext, 116 String name, Class type, 117 String displayName, String shortDescription) 118 { 119 super(type); 120 setValue("changeImmediate", Boolean.FALSE); setName(name); 122 setDisplayName(displayName); 123 setShortDescription(getDescriptionWithType(shortDescription)); 124 125 this.propertyContext = FormPropertyContext.EmptyImpl.getInstance(); 126 setPropertyContext(propertyContext); 127 } 128 129 protected FormProperty(FormPropertyContext propertyContext, Class type) { 130 super(type); 131 setValue("changeImmediate", Boolean.FALSE); 133 this.propertyContext = FormPropertyContext.EmptyImpl.getInstance(); 134 setPropertyContext(propertyContext); 135 } 136 137 protected FormProperty(String name, Class type, 140 String displayName, String shortDescription) 141 { 142 super(type); 143 setValue("changeImmediate", Boolean.FALSE); setName(name); 145 setDisplayName(displayName); 146 setShortDescription(getDescriptionWithType(shortDescription)); 147 148 this.propertyContext = FormPropertyContext.EmptyImpl.getInstance(); 149 } 150 151 protected FormProperty(Class type) { 155 super(type); 156 setValue("changeImmediate", Boolean.FALSE); 158 this.propertyContext = FormPropertyContext.EmptyImpl.getInstance(); 159 } 160 161 private String getDescriptionWithType(String description) { 162 String type = org.openide.util.Utilities.getClassName(getValueType()); 163 return description == null ? 164 FormUtils.getFormattedBundleString("HINT_PropertyType", new Object [] { type }) : 166 FormUtils.getFormattedBundleString("HINT_PropertyTypeWithDescription", new Object [] { type, description }); 168 } 169 170 173 public String getHtmlDisplayName() { 174 if (isChanged()) { 175 return "<b>" + getDisplayName(); } else { 177 return null; 178 } 179 } 180 181 183 public abstract Object getTargetValue() throws IllegalAccessException , 184 InvocationTargetException; 185 186 188 public abstract void setTargetValue(Object value) throws IllegalAccessException , 189 IllegalArgumentException , 190 InvocationTargetException; 191 192 194 public Object getValue() throws IllegalAccessException , 195 InvocationTargetException { 196 Object value = checkCurrentValue(); 199 200 if (valueSet || (propType & DETACHED_READ) == 0) 201 return value; 202 203 return getDefaultValue(); 204 } 205 206 208 public void setValue(Object value) throws IllegalAccessException , 209 IllegalArgumentException , 210 InvocationTargetException 211 { 212 if (fireChanges) 216 value = convertValue(value); 217 218 Object oldValue; 219 if (canRead()) { 220 try { oldValue = getValue(); 222 } 223 catch (Exception e) { oldValue = BeanSupport.NO_VALUE; 225 } 226 } 227 else oldValue = BeanSupport.NO_VALUE; 228 229 if (value instanceof ValueWithEditor) { 230 ValueWithEditor vwpe = (ValueWithEditor) value; 232 value = vwpe.getValue(); 233 PropertyEditor newEditor = vwpe.getPropertyEditor(this); 234 PropertyEditor oldEditor = currentEditor; 235 236 if (newEditor != oldEditor) { 237 boolean fire = fireChanges; 239 fireChanges = false; 240 setCurrentEditor(newEditor); 241 setValue(value); 242 fireChanges = fire; 243 244 if (oldValue == BeanSupport.NO_VALUE) 245 oldValue = null; 247 propertyValueAndEditorChanged( 248 new ValueWithEditor(oldValue, oldEditor), 249 new ValueWithEditor(value, newEditor)); 250 251 return; 252 } 253 } 255 256 if (oldValue != BeanSupport.NO_VALUE) { 257 if (!(value instanceof FormDesignValue) && equals(value, oldValue)) 259 return; } 261 else oldValue = null; 263 if (value == BeanSupport.NO_VALUE) { 264 setChanged(false); 266 propertyValue = value; 267 lastRealValue = null; 268 propertyValueChanged(oldValue, value); 269 return; 270 } 271 272 Object defValue = supportsDefaultValue() ? 273 getDefaultValue() : BeanSupport.NO_VALUE; 274 275 if (canWriteToTarget()) { 276 Object realValue = getRealValue(value); 278 279 if (realValue != FormDesignValue.IGNORED_VALUE) { 281 setTargetValue(realValue); 282 } 283 else if (valueSet && defValue != BeanSupport.NO_VALUE) { 284 setTargetValue(defValue); 285 } 286 287 if (canReadFromTarget()) { 288 lastRealValue = getTargetValue(); 289 292 306 } 307 } 308 309 propertyValue = value; valueSet = true; 311 312 setChanged((propType & (NO_READ_PROP|NO_WRITE_PROP)) == 0 315 && (defValue == BeanSupport.NO_VALUE 316 || !equals(value, defValue))); 317 318 propertyValueChanged(oldValue, value); 320 } 321 322 326 public final Object getRealValue() throws IllegalAccessException , 327 InvocationTargetException { 328 return getRealValue(getValue()); 329 } 330 331 335 protected Object getRealValue(Object value) { 336 return value instanceof FormDesignValue ? 337 ((FormDesignValue)value).getDesignValue() : value; 338 } 339 340 345 public boolean supportsDefaultValue () { 346 return false; 347 } 348 349 public boolean isDefaultValue() { 350 return supportsDefaultValue() ? !isChanged() : true; 351 } 352 353 358 public Object getDefaultValue() { 359 return null; 360 } 361 362 364 public void restoreDefaultValue() throws IllegalAccessException , 365 InvocationTargetException { 366 setChanged(false); 368 369 Object oldValue = null; 370 Object defValue = getDefaultValue(); 371 372 if (canRead()) { 373 try { oldValue = getValue(); 375 if (!(defValue instanceof FormDesignValue) 376 && equals(defValue, oldValue)) 377 return; } 379 catch (Exception e) {} } 381 382 if (canWriteToTarget()) { 383 Object realValue = getRealValue(defValue); 385 386 try { 387 if (realValue != FormDesignValue.IGNORED_VALUE) { 389 setTargetValue(realValue); 390 } 392 else if (defValue != BeanSupport.NO_VALUE) { 393 setTargetValue(defValue); 394 } 396 399 lastRealValue = getTargetValue(); 400 } 401 catch (IllegalArgumentException e) {} } 403 404 propertyValue = defValue; 405 valueSet = true; 406 407 PropertyEditor prEd = findDefaultEditor(); 409 if (prEd != null) 410 setCurrentEditor(prEd); 411 412 propertyValueChanged(oldValue, defValue); 414 } 415 416 421 public void reinstateTarget() throws IllegalAccessException , 422 InvocationTargetException { 423 if (valueSet && canWriteToTarget()) 424 try { 425 Object realValue = getRealValue(propertyValue); 427 428 if (realValue != FormDesignValue.IGNORED_VALUE) { 429 setTargetValue(realValue); 430 lastRealValue = realValue; 431 } 432 else if (isExternalChangeMonitoring()) 433 lastRealValue = getTargetValue(); 434 } 435 catch (IllegalArgumentException e) { } 437 } 438 439 444 public void reinstateProperty() throws IllegalAccessException , 445 InvocationTargetException { 446 boolean mayChanged = canReadFromTarget() 447 && (propType & (NO_READ_PROP|NO_WRITE_PROP)) == 0; 448 449 if (mayChanged) { 450 Object value = getTargetValue(); 451 if (supportsDefaultValue()) { 452 Object defValue = getDefaultValue(); 453 mayChanged = !equals(value, defValue); 454 } 455 if (mayChanged) { 456 propertyValue = value; 457 lastRealValue = value; 458 } 459 } 460 461 valueSet = mayChanged; 462 setChanged(mayChanged); 463 } 464 465 468 470 public boolean canRead() { 471 return (propType & NO_READ_PROP) == 0; 472 } 473 474 476 public boolean canWrite() { 477 return (propType & NO_WRITE_PROP) == 0; 478 } 479 480 public final boolean canReadFromTarget() { 481 return (propType & DETACHED_READ) == 0; 482 } 483 484 public final boolean canWriteToTarget() { 485 return (propType & DETACHED_WRITE) == 0; 486 } 487 488 492 public boolean isChanged() { 493 if (valueChanged && valueSet) { try { 495 checkCurrentValue(); 496 } 497 catch (Exception ex) { 498 } 499 } 500 return valueChanged; 501 } 502 503 505 public void setChanged(boolean changed) { 506 valueChanged = changed; 507 } 508 509 512 519 public PropertyEditor getPropertyEditor() { 520 PropertyEditor prEd; 521 522 if (formPropertyEditor == null) { 523 if (propertyContext.useMultipleEditors()) { 524 formPropertyEditor = new FormPropertyEditor(this); 525 prEd = formPropertyEditor; 526 } 527 else prEd = getCurrentEditor(); 528 } 529 else prEd = formPropertyEditor; 530 531 return prEd; 532 } 533 534 537 public final PropertyEditor getCurrentEditor() { 538 if (currentEditor == null) { 539 currentEditor = findDefaultEditor(); 540 if (currentEditor != null) 541 propertyContext.initPropertyEditor(currentEditor); 542 } 543 return currentEditor; 544 } 545 546 549 public final void setCurrentEditor(PropertyEditor newEditor) { 550 if (newEditor != currentEditor) { 551 if (newEditor != null) 552 propertyContext.initPropertyEditor(newEditor); 553 554 if (formPropertyEditor != null) { 555 if (currentEditor != null) 556 currentEditor.removePropertyChangeListener(formPropertyEditor); 557 if (newEditor != null) 558 newEditor.addPropertyChangeListener(formPropertyEditor); 559 } 560 561 PropertyEditor old = currentEditor; 562 currentEditor = newEditor; 563 currentEditorChanged(old, newEditor); 564 } 565 } 566 567 572 public PropertyEditor getExpliciteEditor() { 573 return null; 574 } 575 576 579 582 public String getJavaInitializationString() { 583 try { 584 Object value = getValue(); 585 if (value == null) 586 return "null"; 588 if (value == BeanSupport.NO_VALUE) 589 return null; 590 591 PropertyEditor ed = getCurrentEditor(); 592 if (ed == null) 593 return null; 594 595 602 if (ed.getValue() != value) 603 ed.setValue(value); 604 return ed.getJavaInitializationString(); 605 } 606 catch (Exception e) { 607 e.printStackTrace(); 608 } 609 return null; 610 } 611 612 616 String getPartialSetterCode(String javaInitStr) { 617 if (javaInitStr == null) 618 return null; 619 620 Method writeMethod = getWriteMethod(); 621 if (writeMethod == null) 622 return null; 623 624 return writeMethod.getName() + "(" + javaInitStr + ")"; } 626 627 631 String getWholeSetterCode(String javaInitStr) { 632 return null; 633 } 634 635 640 protected Method getWriteMethod() { 641 return null; 642 } 643 644 647 public String getPreCode() { 648 return preCode; 649 } 650 651 654 public String getPostCode() { 655 return postCode; 656 } 657 658 661 public void setPreCode(String value) { 662 preCode = value; 663 } 664 665 668 public void setPostCode(String value) { 669 postCode = value; 670 } 671 672 674 public FormPropertyContext getPropertyContext() { 675 return propertyContext; 676 } 677 678 public void setPropertyContext(FormPropertyContext newContext) { 679 if (newContext == null) 680 newContext = FormPropertyContext.EmptyImpl.getInstance(); 681 if (propertyContext != null 682 && formPropertyEditor != null 683 && propertyContext.useMultipleEditors() 684 != newContext.useMultipleEditors()) 685 { 686 if (currentEditor != null) 687 currentEditor.removePropertyChangeListener(formPropertyEditor); 688 formPropertyEditor = null; 689 } 690 691 propertyContext = newContext; 692 693 if (currentEditor != null) 694 propertyContext.initPropertyEditor(currentEditor); 695 } 696 697 public int getAccessType() { 698 return propType; 699 } 700 701 public void setAccessType(int type) { 702 if (type >= 0) 703 propType = type; 704 } 705 706 public boolean isExternalChangeMonitoring() { 707 return externalChangeMonitoring && propType == NORMAL_RW; 708 } 709 710 public void setExternalChangeMonitoring(boolean val) { 711 externalChangeMonitoring = val; 712 } 713 714 716 public void addPropertyChangeListener(PropertyChangeListener l) { 717 synchronized (this) { 718 if (changeSupport == null) 719 changeSupport = new PropertyChangeSupport(this); 720 } 721 changeSupport.addPropertyChangeListener(l); 722 } 723 724 public void removePropertyChangeListener(PropertyChangeListener l) { 725 if (changeSupport != null) 726 changeSupport.removePropertyChangeListener(l); 727 } 728 729 public void addVetoableChangeListener(VetoableChangeListener l) { 730 synchronized (this) { 731 if (vetoableChangeSupport == null) 732 vetoableChangeSupport = new VetoableChangeSupport(this); 733 } 734 vetoableChangeSupport.addVetoableChangeListener(l); 735 } 736 737 public void removeVetoableChangeListener(VetoableChangeListener l) { 738 if (vetoableChangeSupport != null) 739 vetoableChangeSupport.removeVetoableChangeListener(l); 740 } 741 742 public boolean isChangeFiring() { 743 return fireChanges; 744 } 745 746 public void setChangeFiring(boolean fire) { 747 fireChanges = fire; 748 } 749 750 protected void propertyValueChanged(Object old, Object current) { 751 if (fireChanges) { 752 try { 753 firePropertyChange(PROP_VALUE, old, current); 754 } 755 catch (PropertyVetoException ex) { 756 boolean fire = fireChanges; 757 fireChanges = false; 758 try { 759 setValue(old); 760 } 761 catch (Exception ex2) {} fireChanges = fire; 763 } 764 } 765 } 766 767 protected void currentEditorChanged(PropertyEditor old, 768 PropertyEditor current) 769 { 770 if (fireChanges) { 771 try { 772 firePropertyChange(CURRENT_EDITOR, old, current); 773 } 774 catch (PropertyVetoException ex) {} } 776 } 777 778 protected void propertyValueAndEditorChanged(ValueWithEditor old, 779 ValueWithEditor current) 780 { 781 if (fireChanges) { 782 try { 783 firePropertyChange(PROP_VALUE_AND_EDITOR, old, current); 784 } 785 catch (PropertyVetoException ex) { 786 boolean fire = fireChanges; 787 fireChanges = false; 788 try { 789 setValue(old); 790 } 791 catch (Exception ex2) {} fireChanges = fire; 793 } 794 } 795 } 796 797 private void firePropertyChange(String propName, Object old, Object current) 798 throws PropertyVetoException 799 { 800 if (vetoableChangeSupport != null && !CURRENT_EDITOR.equals(propName)) { 801 vetoableChangeSupport.fireVetoableChange(propName, old, current); 802 } 803 if (changeSupport != null) { 804 changeSupport.firePropertyChange(propName, old, current); 805 } 806 } 807 808 public void addValueConvertor(ValueConvertor conv) { 809 synchronized (this) { 810 if (convertors == null) 811 convertors = new java.util.LinkedList <ValueConvertor>(); 812 else 813 convertors.remove(conv); 814 convertors.add(conv); 815 } 816 } 817 818 public void removeValueConvertor(ValueConvertor conv) { 819 synchronized (this) { 820 if (convertors != null) 821 convertors.remove(conv); 822 } 823 } 824 825 protected Object convertValue(Object value) { 826 if (convertors != null) { 827 for (ValueConvertor conv : convertors) { 828 Object val = conv.convert(value, this); 829 if (val != value) 830 return val; 831 } 832 } 833 return value; 834 } 835 836 839 private Object checkCurrentValue() 840 throws IllegalAccessException , InvocationTargetException 841 { 842 if (valueSet) { 843 Object value = null; 844 845 if (isExternalChangeMonitoring()) { 846 value = getTargetValue(); 847 if (!equals(value, lastRealValue) 848 && (value == null || propertyValue == null 849 || value.getClass().isAssignableFrom(propertyValue.getClass()))) 850 { valueSet = false; 852 setChanged(false); 853 lastRealValue = null; 861 return value; 862 } 864 } 865 return propertyValue; 866 } 867 return (propType & DETACHED_READ) == 0 ? getTargetValue() : null; 868 } 869 870 PropertyEditor findDefaultEditor() { 871 PropertyEditor defaultEditor = getExpliciteEditor(); 872 if (defaultEditor != null) 873 return defaultEditor; 874 return FormPropertyEditorManager.findEditor(this); 875 } 876 877 879 private static boolean equals(Object obj1, Object obj2) { 881 if (obj1 == obj2) 882 return true; 883 884 if (obj1 == null || obj2 == null) 885 return false; 886 887 Class cls1 = obj1.getClass(); 888 Class cls2 = obj2.getClass(); 889 890 if (!cls1.isArray() || !cls1.equals(cls2)) 891 return obj1.equals(obj2); 892 893 Class cType = cls1.getComponentType(); 895 if (!cType.isPrimitive()) { 896 Object [] array1 = (Object []) obj1; 897 Object [] array2 = (Object []) obj2; 898 if (array1.length != array2.length) 899 return false; 900 for (int i=0; i < array1.length; i++) 901 if (!equals(array1[i], array2[i])) 902 return false; 903 return true; 904 } 905 906 if (Integer.TYPE.equals(cType)) { 907 int[] array1 = (int[]) obj1; 908 int[] array2 = (int[]) obj2; 909 if (array1.length != array2.length) 910 return false; 911 for (int i=0; i < array1.length; i++) 912 if (array1[i] != array2[i]) 913 return false; 914 return true; 915 } 916 917 if (Boolean.TYPE.equals(cType)) { 918 boolean[] array1 = (boolean[]) obj1; 919 boolean[] array2 = (boolean[]) obj2; 920 if (array1.length != array2.length) 921 return false; 922 for (int i=0; i < array1.length; i++) 923 if (array1[i] != array2[i]) 924 return false; 925 return true; 926 } 927 928 if (Long.TYPE.equals(cType)) { 929 long[] array1 = (long[]) obj1; 930 long[] array2 = (long[]) obj2; 931 if (array1.length != array2.length) 932 return false; 933 for (int i=0; i < array1.length; i++) 934 if (array1[i] != array2[i]) 935 return false; 936 return true; 937 } 938 939 if (Double.TYPE.equals(cType)) { 940 double[] array1 = (double[]) obj1; 941 double[] array2 = (double[]) obj2; 942 if (array1.length != array2.length) 943 return false; 944 for (int i=0; i < array1.length; i++) 945 if (array1[i] != array2[i]) 946 return false; 947 return true; 948 } 949 950 if (Byte.TYPE.equals(cType)) { 951 byte[] array1 = (byte[]) obj1; 952 byte[] array2 = (byte[]) obj2; 953 if (array1.length != array2.length) 954 return false; 955 for (int i=0; i < array1.length; i++) 956 if (array1[i] != array2[i]) 957 return false; 958 return true; 959 } 960 961 if (Character.TYPE.equals(cType)) { 962 char[] array1 = (char[]) obj1; 963 char[] array2 = (char[]) obj2; 964 if (array1.length != array2.length) 965 return false; 966 for (int i=0; i < array1.length; i++) 967 if (array1[i] != array2[i]) 968 return false; 969 return true; 970 } 971 972 if (Float.TYPE.equals(cType)) { 973 float[] array1 = (float[]) obj1; 974 float[] array2 = (float[]) obj2; 975 if (array1.length != array2.length) 976 return false; 977 for (int i=0; i < array1.length; i++) 978 if (array1[i] != array2[i]) 979 return false; 980 return true; 981 } 982 983 if (Short.TYPE.equals(cType)) { 984 short[] array1 = (short[]) obj1; 985 short[] array2 = (short[]) obj2; 986 if (array1.length != array2.length) 987 return false; 988 for (int i=0; i < array1.length; i++) 989 if (array1[i] != array2[i]) 990 return false; 991 return true; 992 } 993 994 return false; 995 } 996 997 1020 1021 1023 1027 public interface ValueConvertor { 1028 public Object convert(Object value, FormProperty property); 1029 } 1030 1031 1033 public static final class ValueWithEditor { 1034 private Object value; 1035 private PropertyEditor propertyEditor; 1036 private int propertyEditorIndex; 1037 1038 ValueWithEditor(Object value, PropertyEditor propertyEditor) { 1039 this.value = value; 1040 this.propertyEditor = propertyEditor; 1041 } 1042 1043 ValueWithEditor(Object value, int propertyEditorIndex) { 1044 this.value = value; 1045 this.propertyEditorIndex = propertyEditorIndex; 1046 } 1047 1048 public Object getValue() { 1049 return value; 1050 } 1051 1052 public PropertyEditor getPropertyEditor() { 1053 return propertyEditor; 1054 } 1055 1056 PropertyEditor getPropertyEditor(FormProperty property) { 1057 if (propertyEditor != null) 1058 return propertyEditor; 1059 if (propertyEditorIndex < 0) 1060 return null; 1061 1062 PropertyEditor pe = property.getPropertyEditor(); 1063 if (pe instanceof FormPropertyEditor) { 1064 FormPropertyEditor fpe = (FormPropertyEditor) pe; 1065 PropertyEditor[] allEds = fpe.getAllEditors(); 1066 if (propertyEditorIndex < allEds.length) 1067 return allEds[propertyEditorIndex]; 1068 } 1069 1070 return null; 1071 } 1072 } 1073 1074 public static Object getEnclosedValue(Object value) { 1075 return value instanceof ValueWithEditor ? ((ValueWithEditor)value).getValue() : value; 1076 } 1077 1078 1080 public static interface Filter { 1081 public boolean accept(FormProperty property); 1082 } 1083 1084 public static final Filter CHANGED_PROPERTY_FILTER = new Filter() { 1085 public boolean accept(FormProperty property) { 1086 return property.isChanged(); 1087 } 1088 }; 1089} 1090 | Popular Tags |