1 19 package org.openide.explorer.propertysheet; 20 21 import java.util.logging.Level ; 22 import java.util.logging.Logger ; 23 import java.util.prefs.Preferences ; 24 import javax.accessibility.Accessible ; 25 import javax.accessibility.AccessibleContext ; 26 import org.openide.*; 27 import org.openide.nodes.*; 28 import org.openide.nodes.Node.*; 29 import org.openide.util.*; 30 31 import java.awt.*; 32 import java.awt.event.*; 33 import java.awt.image.BufferedImage ; 34 35 import java.beans.*; 36 37 import java.io.PrintWriter ; 38 import java.io.StringWriter ; 39 40 import java.lang.reflect.InvocationTargetException ; 41 42 import java.text.MessageFormat ; 43 44 import java.util.*; 45 import javax.accessibility.AccessibleRole ; 46 47 import javax.swing.*; 48 import javax.swing.border.Border ; 49 import javax.swing.plaf.SplitPaneUI ; 50 import javax.swing.plaf.basic.BasicSplitPaneDivider ; 51 import javax.swing.plaf.basic.BasicSplitPaneUI ; 52 import javax.swing.plaf.metal.*; 53 54 import org.netbeans.modules.openide.explorer.UIException; 55 56 57 60 final class PropUtils { 61 63 static final boolean noCustomButtons = Boolean.getBoolean("netbeans.ps.noCustomButtons"); 65 66 static boolean forceRadioButtons = 67 Boolean.getBoolean("netbeans.ps.forceRadioButtons"); 69 70 71 static final boolean noCheckboxCaption = !Boolean.getBoolean("netbeans.ps.checkboxCaption"); 73 77 static final boolean hideSingleExpansion = Boolean.getBoolean("netbeans.ps.hideSingleExpansion"); static final boolean neverMargin = true; 79 80 83 86 static final boolean psCommitOnFocusLoss = !Boolean.getBoolean("netbeans.ps.NoCommitOnFocusLoss"); 87 88 90 private static final String KEY_ALTBG = "Tree.altbackground"; 92 95 private static final String KEY_SETBG = "PropSheet.setBackground"; 97 100 private static final String KEY_SELSETBG = "PropSheet.selectedSetBackground"; 102 105 private static final String KEY_SETFG = "PropSheet.setForeground"; 107 110 private static final String KEY_SELSETFG = "PropSheet.selectedSetForeground"; 112 114 private static final String KEY_ICONMARGIN = "netbeans.ps.iconmargin"; 116 118 static final String KEY_ROWHEIGHT = "netbeans.ps.rowheight"; 120 private static Preferences preferences() { 121 return NbPreferences.forModule(PropUtils.class); 122 } 123 124 125 private static final String PREF_KEY_SHOWDESCRIPTION = "showDescriptionArea"; 127 128 private static final String PREF_KEY_CLOSEDSETNAMES = "closedSetNames"; 130 131 private static final String PREF_KEY_SORTORDER = "sortOrder"; 133 134 static Color disFg = null; 135 136 138 static float fsfactor = -1f; 139 140 141 static int minW = -1; 142 143 144 static int minH = -1; 145 146 147 private static Color tfFg = null; 148 149 150 private static Color tfBg = null; 151 152 154 static Boolean noAltBg = null; 155 156 159 static int marginWidth = -1; 160 161 162 private static int iconMargin = -1; 163 164 167 static Color selectedSetRendererColor = null; 168 169 170 static Color setRendererColor = null; 171 172 173 static int spinnerHeight = -1; 174 175 176 static Color controlColor = null; 177 178 179 static Color shadowColor = null; 180 181 182 static Color altBg = null; 183 184 185 private static String bptn = null; 186 187 188 private static Comparator comp = null; 189 190 191 private static int textMargin = -1; 192 193 194 private static Color setForegroundColor = null; 195 196 197 private static Color selectedSetForegroundColor = null; 198 199 204 private static Boolean useOptimizedCustomButtonPainting = null; 205 static boolean isAqua = "Aqua".equals(UIManager.getLookAndFeel().getID()); private static Graphics scratchGraphics = null; 207 208 210 211 private final static Comparator<Node.Property> SORTER_TYPE = new Comparator<Node.Property>() { 212 public int compare(Node.Property l, Node.Property r) { 213 214 Class t1 = l.getValueType(); 215 Class t2 = r.getValueType(); 216 String s1 = (t1 != null) ? t1.getName() : ""; String s2 = (t2 != null) ? t2.getName() : ""; 219 int s = s1.compareToIgnoreCase(s2); 220 221 if (s != 0) { 222 return s; 223 } 224 225 s1 = l.getDisplayName(); 226 s2 = r.getDisplayName(); 227 228 return s1.compareToIgnoreCase(s2); 229 } 230 231 public String toString() { 232 return "Type comparator"; } 234 }; 235 236 237 private final static Comparator<Node.Property> SORTER_NAME = new Comparator<Node.Property>() { 238 public int compare(Node.Property l, Node.Property r) { 239 String s1 = l.getDisplayName(); 240 String s2 = r.getDisplayName(); 241 242 return String.CASE_INSENSITIVE_ORDER.compare(s1, s2); 243 } 244 245 public String toString() { 246 return "Name comparator"; } 248 }; 249 250 private static java.util.List <String > missing = null; 251 252 private static Set<Property> externallyEdited = new HashSet<Property>(3); 256 257 258 private PropUtils() { 259 } 261 262 269 static boolean useOptimizedCustomButtonPainting() { 270 if (useOptimizedCustomButtonPainting == null) { 271 if ("com.sun.java.swing.plaf.WindowsLookAndFeel".equals(UIManager.getLookAndFeel())) { useOptimizedCustomButtonPainting = Boolean.valueOf(isXPTheme()); 273 } else { 274 useOptimizedCustomButtonPainting = Boolean.valueOf("Aqua".equals(UIManager.getLookAndFeel().getID())); 275 } 276 } 277 278 return useOptimizedCustomButtonPainting.booleanValue(); 279 } 280 281 static void log(Class clazz, String msg, boolean dumpstack) { 282 log(clazz, msg); 283 284 if (dumpstack) { 285 dumpStack(clazz); 286 } 287 } 288 289 static void log(Class clazz, String msg) { 291 Logger.getLogger(clazz.getName()).fine(msg); 292 } 293 294 static void log(Class clazz, FocusEvent fe) { 295 if (isLoggable(clazz)) { 296 StringBuffer sb = new StringBuffer (30); 297 focusEventToString(fe, sb); 298 log(clazz, sb.toString()); 299 } 300 } 301 302 static boolean isLoggable(Class clazz) { 303 return Logger.getLogger(clazz.getName()).isLoggable(Level.FINE); 304 } 305 306 static void logFocusOwner(Class clazz, String where) { 307 if (isLoggable(clazz)) { 308 StringBuffer sb = new StringBuffer (where); 309 sb.append(" focus owner: "); 311 Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 312 compToString(owner, sb); 313 } 314 } 315 316 static void focusEventToString(FocusEvent fe, final StringBuffer sb) { 317 Component target = (Component) fe.getSource(); 318 Component opposite = (Component) fe.getOppositeComponent(); 319 sb.append(" focus "); sb.append((fe.getID() == FocusEvent.FOCUS_GAINED) ? " gained by " : " lost by "); compToString(target, sb); 322 sb.append((fe.getID() == FocusEvent.FOCUS_GAINED) ? " from " : " to "); compToString(opposite, sb); 324 sb.append(" isTemporary: "); sb.append(fe.isTemporary()); 326 } 327 328 static void compToString(Component c, final StringBuffer sb) { 329 if (c == null) { 330 sb.append(" null "); 332 return; 333 } 334 335 String name = c.getName(); 336 Class clazz = c.getClass(); 337 String classname = clazz.getName(); 338 int i = classname.lastIndexOf('.'); 339 340 if ((i != -1) && (i != (classname.length() - 1))) { 341 classname = classname.substring(i + 1); 342 } 343 344 if (name != null) { 345 sb.append("\""); sb.append(name); 347 sb.append("\" ("); sb.append(classname); 349 sb.append(") "); } else { 351 sb.append(' '); sb.append(classname); 353 sb.append(' '); } 355 356 if (!c.isVisible()) { 357 sb.append(" [NOT VISIBLE] "); } 359 360 if (!c.isDisplayable()) { 361 sb.append(" [HAS NO PARENT COMPONENT] "); } 363 } 364 365 public static void dumpStack(Class clazz) { 366 if (Logger.getLogger(clazz.getName()).isLoggable(Level.FINE)) { 367 StringWriter sw = new StringWriter (); 368 new Throwable ().printStackTrace(new PrintWriter (sw)); 369 log(clazz, sw.getBuffer().toString()); 370 } 371 } 372 373 375 static Color getButtonColor() { 376 return UIManager.getColor("netbeans.ps.buttonColor"); } 378 379 381 static int getCustomButtonWidth() { 382 Icon ic = getCustomButtonIcon(); 383 384 return ic.getIconWidth() + (isAqua ? 5 : 3); 385 } 386 387 388 static boolean checkEnabled(Component c, PropertyEditor editor, PropertyEnv env) { 389 if (editor instanceof NoPropertyEditorEditor) { 390 return false; 391 } 392 393 if (env != null) { 394 Boolean canEditAsText = (Boolean ) env.getFeatureDescriptor().getValue("canEditAsText"); 396 if (!env.isEditable() || Boolean.FALSE.equals(canEditAsText)) { 397 return false; 398 } 399 } 400 401 return true; 402 } 403 404 406 static Graphics getScratchGraphics(Component c) { 407 if (scratchGraphics == null) { 408 scratchGraphics = new BufferedImage (1, 1, BufferedImage.TYPE_INT_RGB).getGraphics(); 409 } 410 411 return scratchGraphics; 412 } 413 414 418 static Color getErrorColor() { 419 Color result = UIManager.getColor("nb.errorForeground"); 422 if (result == null) { 423 result = Color.RED; 424 } 425 426 return result; 427 } 428 429 430 static Color getDisabledForeground() { 431 if (disFg == null) { 432 disFg = UIManager.getColor("textInactiveText"); 434 if (disFg == null) { 435 disFg = Color.GRAY; 436 } 437 } 438 439 return disFg; 440 } 441 442 445 static float getFontSizeFactor() { 446 if (fsfactor == -1) { 447 Font f = UIManager.getFont("controlFont"); 449 if (f == null) { 450 JLabel jl = new JLabel(); 451 f = jl.getFont(); 452 } 453 454 int baseSize = 12; fsfactor = baseSize / f.getSize(); 456 } 457 458 return fsfactor; 459 } 460 461 463 static int getMinimumPropPanelWidth() { 464 if (minW == -1) { 465 int base = 50; 466 minW = Math.round(base * getFontSizeFactor()); 467 } 468 469 return minW; 470 } 471 472 474 static int getMinimumPropPanelHeight() { 475 if (minH == -1) { 476 int base = 18; 477 minH = Math.round(base * getFontSizeFactor()); 478 } 479 480 return minH; 481 } 482 483 485 static Dimension getMinimumPanelSize() { 486 return new Dimension(getMinimumPropPanelWidth(), getMinimumPropPanelHeight()); 487 } 488 489 491 static boolean updateProp(PropertyModel mdl, PropertyEditor ed, String title) { 492 Object newValue = ed.getValue(); 494 Object o = noDlgUpdateProp(mdl, ed); 495 496 if (o instanceof Exception ) { 498 if( o instanceof InvocationTargetException ) 499 o = ((InvocationTargetException )o).getTargetException(); 500 processThrowable((Exception ) o, title, newValue); 501 } 502 503 boolean result = (o instanceof Boolean ) ? ((Boolean ) o).booleanValue() : false; 504 505 return result; 507 } 508 509 514 static Object noDlgUpdateProp(PropertyModel mdl, PropertyEditor ed) { 515 Object newValue = ed.getValue(); 517 Object result = Boolean.FALSE; 518 519 try { 520 try { 521 Object oldValue = mdl.getValue(); 522 523 int selBeans = 0; 524 if( mdl instanceof NodePropertyModel ) { 525 Object [] beans = ((NodePropertyModel)mdl).getBeans(); 526 if( null != beans ) 527 selBeans = beans.length; 528 } 529 530 if (((newValue != null) && !newValue.equals(oldValue)) 532 || ((newValue == null) && (oldValue != null || selBeans > 1))) { 533 mdl.setValue(newValue); 534 result = Boolean.TRUE; 535 } else { 536 } 538 } catch (ProxyNode.DifferentValuesException dve) { 539 mdl.setValue(newValue); 542 result = Boolean.TRUE; 543 } 544 } catch (Exception e) { 545 result = e; 546 } 547 548 return result; 549 } 550 551 556 static Exception updatePropertyEditor(PropertyEditor ed, Object value) { 557 Exception result = null; 559 560 try { 561 if (value instanceof String ) { 562 ed.setAsText((String ) value); 563 } else { 564 ed.setValue(value); 565 } 566 } catch (Exception e) { 567 result = e; 568 } 569 570 return result; 572 } 573 574 575 static boolean updateProp(InplaceEditor ine) { 576 Component c = ine.getComponent(); 578 Cursor oldCursor = c.getCursor(); 579 580 try { 581 c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 582 583 Object o = ine.getValue(); 584 Exception e = updatePropertyEditor(ine.getPropertyEditor(), o); 585 586 String newValString = (o == null) ? NbBundle.getMessage(PropUtils.class, "NULL") : o.toString(); 589 if (e != null) { 590 PropertyModel pm = ine.getPropertyModel(); 591 String propName; 592 593 if (pm instanceof NodePropertyModel) { 594 Node.Property p = ((NodePropertyModel) pm).getProperty(); 595 propName = p.getDisplayName(); 596 } else if (pm instanceof DefaultPropertyModel) { 597 propName = ((DefaultPropertyModel) pm).propertyName; 598 } else { 599 propName = NbBundle.getMessage(PropUtils.class, "MSG_unknown_property_name"); } 602 603 processThrowable(e, propName, newValString); 604 } 605 606 boolean result = (e == null) 607 ? PropUtils.updateProp(ine.getPropertyModel(), ine.getPropertyEditor(), newValString) : false; 608 609 return result; 611 } finally { 612 c.setCursor(oldCursor); 613 } 614 } 615 616 618 private static void processThrowable(Throwable throwable, String title, Object newValue) { 619 if (throwable instanceof ThreadDeath ) { 621 throw (ThreadDeath ) throwable; 622 } 623 624 String locMsg = Exceptions.findLocalizedMessage(throwable); 625 626 if (locMsg != null 627 && (throwable.getLocalizedMessage() != throwable.getMessage())) { 629 String msg = MessageFormat.format( 630 NbBundle.getMessage(PropUtils.class, "FMT_ErrorSettingProperty"), new Object [] { newValue, title } 631 ); UIException.annotateUser(throwable, msg, 633 throwable.getLocalizedMessage(), throwable, 634 new Date()); 635 } else if (throwable instanceof NumberFormatException ) { 636 UIException.annotateUser(throwable, throwable.getMessage(), 638 MessageFormat.format(NbBundle.getMessage(PropUtils.class, 639 "FMT_BAD_NUMBER_FORMAT"), 640 new Object []{newValue}), 641 null, null); 642 } 643 644 Exceptions.printStackTrace(throwable); 645 } 646 647 651 static synchronized String findLocalizedMessage(Throwable throwable, Object newValue, String title) { 652 try { 653 if (throwable == null) { 654 return null; 658 } 659 660 if (throwable.getLocalizedMessage() != throwable.getMessage()) { 661 return throwable.getLocalizedMessage(); 662 } 663 664 String msg = Exceptions.findLocalizedMessage(throwable); 665 if (msg != null) { 666 return msg; 667 } 668 669 if (throwable instanceof NumberFormatException ) { 670 return MessageFormat.format( 672 NbBundle.getMessage(PropUtils.class, "FMT_BAD_NUMBER_FORMAT"), new Object [] { newValue } 674 ); 675 } 676 679 return MessageFormat.format( 681 NbBundle.getMessage(PropUtils.class, "FMT_CannotUpdateProperty"), new Object [] { newValue, title } 682 ); } catch (Exception e) { 684 Exceptions.printStackTrace(e); 687 688 return null; 689 } 690 } 691 692 694 static Comparator<Property> getComparator(int sortingMode) { 695 switch (sortingMode) { 696 case PropertySheet.UNSORTED: 697 return null; 698 699 case PropertySheet.SORTED_BY_NAMES: 700 return SORTER_NAME; 701 702 case PropertySheet.SORTED_BY_TYPES: 703 return SORTER_TYPE; 704 705 default: 706 throw new IllegalArgumentException ("Unknown sorting mode: " + Integer.toString(sortingMode)); } 708 } 709 710 718 public static javax.swing.plaf.ComboBoxUI createComboUI(JComboBox box, boolean tableUI) { 719 return new CleanComboUI(tableUI); 720 } 721 722 725 private static java.util.List <String > getMissing() { 726 if (missing == null) { 727 missing = new ArrayList<String >(); 728 } 729 730 return missing; 731 } 732 733 738 static PropertyEditor getPropertyEditor(Class <?> c) { 739 PropertyEditor result = PropertyEditorManager.findEditor(c); 740 741 if (result == null && Enum .class.isAssignableFrom(c)) { 742 result = new EnumPropertyEditor(c.asSubclass(Enum .class)); 744 } 745 746 if (result == null) { 747 result = new NoPropertyEditorEditor(); 748 } 749 750 return result; 751 } 752 753 759 static PropertyEditor getPropertyEditor(Property p) { 760 return getPropertyEditor(p, true); 761 } 762 763 774 static PropertyEditor getPropertyEditor(Property p, boolean updateEditor) { 775 PropertyEditor result = p.getPropertyEditor(); 776 777 if (p instanceof Node.IndexedProperty && (result == null)) { 783 result = new IndexedPropertyEditor(); 784 785 p.setValue(PropertyEnv.PROP_CHANGE_IMMEDIATE, Boolean.FALSE); 787 } 788 789 if (result == null) { 790 result = getPropertyEditor(p.getValueType()); } 792 793 if (result == null) { 795 java.util.List <String > missing = getMissing(); 796 String type = p.getValueType().getName(); 797 798 if (!(missing.contains(type))) { 799 Logger.getAnonymousLogger().fine( 800 "No property editor registered for type " + type 801 ); missing.add(type); 803 } 804 805 result = new NoPropertyEditorEditor(); 806 } else if (p.canRead()) { 807 try { 808 try { 809 try { 810 if ( 811 ((p.getValueType() == Boolean .class) || (p.getValueType() == Boolean.TYPE)) && 812 (p.getValue() == null) 813 ) { 814 result = new Boolean3WayEditor(); 817 } 818 819 if (updateEditor) { 820 updateEdFromProp(p, result, p.getDisplayName()); 821 } 822 } catch (ProxyNode.DifferentValuesException dve) { 823 if ((p.getValueType() == Boolean .class) || (p.getValueType() == Boolean.TYPE)) { 824 result = new Boolean3WayEditor(); 825 } else { 826 if(result instanceof ExPropertyEditor) 827 result = new ExDifferentValuesEditor(result); 828 else 829 result = new DifferentValuesEditor(result); 830 } 831 } 832 } catch (IllegalAccessException iae) { 833 throw (IllegalStateException ) new IllegalStateException ("Error getting property value").initCause(iae); 834 } 835 } catch (InvocationTargetException ite) { 836 throw (IllegalStateException ) new IllegalStateException ("Error getting property value").initCause(ite); 837 } 838 } 839 840 return result; 841 } 842 843 845 private static void updateEdFromProp(Property p, PropertyEditor ed, String title) 846 throws ProxyNode.DifferentValuesException, IllegalAccessException , InvocationTargetException { 847 Object newValue = p.getValue(); 848 849 if (newValue instanceof String && (((String ) newValue).length() > 2048)) { 852 ed.setValue(newValue); 853 854 return; 855 } 856 857 Object oldValue = ed.getValue(); 858 859 if ((newValue == null) && (oldValue == null)) { 860 return; 861 } 862 863 if (((newValue != null) && !newValue.equals(oldValue)) || ((newValue == null) && (oldValue != null))) { 865 if ( 872 oldValue instanceof Object [] && newValue instanceof Object [] && 873 Arrays.equals((Object []) oldValue, (Object []) newValue) 874 ) { 875 return; 876 } 877 878 ed.setValue(newValue); 880 } 881 } 882 883 886 static Color getControlColor() { 887 if (controlColor == null) { 888 deriveColorsAndMargin(); 889 } 890 891 return controlColor; 892 } 893 894 896 static Color getShadowColor() { 897 if (shadowColor == null) { 898 deriveColorsAndMargin(); 899 } 900 901 return shadowColor; 902 } 903 904 906 static Color getAltBg() { 907 if (altBg == null) { 908 deriveColorsAndMargin(); 909 } 910 911 return altBg; 912 } 913 914 919 static boolean noAltBg() { 920 if (noAltBg == null) { 921 noAltBg = (UIManager.getColor(KEY_ALTBG) == null) ? Boolean.TRUE : Boolean.FALSE; 923 } 924 925 return noAltBg.booleanValue(); 926 } 927 928 934 static Color getTextFieldBackground() { 935 if (tfBg == null) { 936 tfBg = UIManager.getColor("TextField.background"); 938 if (tfBg == null) { 939 tfBg = UIManager.getColor("text"); } 941 942 if (tfBg == null) { 943 tfBg = Color.WHITE; 944 } 945 } 946 947 return tfBg; 948 } 949 950 953 static Color getTextFieldForeground() { 954 if (tfFg == null) { 955 tfFg = UIManager.getColor("TextField.foreground"); 957 if (tfFg == null) { 958 tfFg = UIManager.getColor("textText"); } 960 961 if (tfFg == null) { 962 tfFg = Color.BLACK; 963 } 964 } 965 966 return tfFg; 967 } 968 969 970 private static void deriveColorsAndMargin() { 971 controlColor = UIManager.getColor("control"); 973 if (controlColor == null) { 974 controlColor = Color.LIGHT_GRAY; 975 } 976 977 int red; 978 int green; 979 int blue; 980 981 boolean windows = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel".equals( 982 UIManager.getLookAndFeel().getClass().getName() 983 ); 984 985 boolean aqua = "Aqua".equals(UIManager.getLookAndFeel().getID()); 986 987 setRendererColor = UIManager.getColor(KEY_SETBG); selectedSetRendererColor = UIManager.getColor(KEY_SELSETBG); 990 if (setRendererColor == null) { 991 if (aqua) { 992 setRendererColor = new Color(225, 235, 240); 993 } else { 994 if (setRendererColor == null) { 995 red = adjustColorComponent(controlColor.getRed(), -25, -25); 996 green = adjustColorComponent(controlColor.getGreen(), -25, -25); 997 blue = adjustColorComponent(controlColor.getBlue(), -25, -25); 998 setRendererColor = new Color(red, green, blue); 999 } 1000 } 1001 } 1002 1003 if (aqua) { 1004 selectedSetRendererColor = UIManager.getColor("Table.selectionBackground"); 1005 } 1006 1007 if (selectedSetRendererColor == null) { 1008 Color col = windows ? UIManager.getColor("Table.selectionBackground") 1009 : UIManager.getColor("activeCaptionBorder"); 1011 if (col == null) { 1012 col = Color.BLUE; 1013 } 1014 1015 red = adjustColorComponent(col.getRed(), -25, -25); 1016 green = adjustColorComponent(col.getGreen(), -25, -25); 1017 blue = adjustColorComponent(col.getBlue(), -25, -25); 1018 selectedSetRendererColor = new Color(red, green, blue); 1019 } 1020 1021 shadowColor = UIManager.getColor("controlShadow"); 1023 if (shadowColor == null) { 1024 shadowColor = Color.GRAY; 1025 } 1026 1027 setForegroundColor = UIManager.getColor(KEY_SETFG); 1028 1029 if (setForegroundColor == null) { 1030 setForegroundColor = UIManager.getColor("Table.foreground"); 1032 if (setForegroundColor == null) { 1033 setForegroundColor = UIManager.getColor("textText"); 1034 1035 if (setForegroundColor == null) { 1036 setForegroundColor = Color.BLACK; 1037 } 1038 } 1039 } 1040 1041 selectedSetForegroundColor = UIManager.getColor(KEY_SELSETFG); 1042 1043 if (selectedSetForegroundColor == null) { 1044 selectedSetForegroundColor = UIManager.getColor("Table.selectionForeground"); 1046 if (selectedSetForegroundColor == null) { 1047 selectedSetForegroundColor = Color.WHITE; 1048 } 1049 } 1050 1051 altBg = UIManager.getColor(KEY_ALTBG); 1053 if (altBg == null) { 1054 altBg = UIManager.getColor("Tree.background"); 1056 if (altBg == null) { 1057 altBg = Color.WHITE; 1058 } 1059 1060 noAltBg = Boolean.TRUE; 1061 } else { 1062 noAltBg = Boolean.FALSE; 1063 } 1064 1065 Icon collapsedIcon = UIManager.getIcon("Tree.collapsedIcon"); Icon expandedIcon = UIManager.getIcon("Tree.expandedIcon"); 1068 assert collapsedIcon != null: "no Tree.collapsedIcon found"; 1069 assert expandedIcon != null: "no Tree.expandedIcon found"; 1070 1071 1072 int iconSize = collapsedIcon.getIconWidth(); 1073 if (collapsedIcon != null) { 1074 marginWidth = Math.max(14, iconSize - 2); 1075 } else { 1076 marginWidth = 13; 1078 } 1079 1080 Integer i = (Integer ) UIManager.get(KEY_ICONMARGIN); 1082 if (i != null) { 1083 iconMargin = i.intValue(); 1084 } else { 1085 if ( 1086 "com.sun.java.swing.plaf.windows.WindowsLookAndFeel".equals( 1087 UIManager.getLookAndFeel().getClass().getName() 1088 ) 1089 ) { 1090 iconMargin = 4; 1091 } else { 1092 iconMargin = 0; 1093 } 1094 } 1095 1096 i = (Integer ) UIManager.get(KEY_ROWHEIGHT); 1098 if (i != null) { 1099 spinnerHeight = i.intValue(); 1100 } else { 1101 spinnerHeight = iconSize; 1102 } 1103 } 1104 1105 1107 static Icon getExpandedIcon() { 1108 Icon expandedIcon = UIManager.getIcon("Tree.expandedIcon"); assert expandedIcon != null: "no Tree.expandedIcon found"; 1110 return expandedIcon; 1111 } 1112 1113 1115 static Icon getCollapsedIcon() { 1116 Icon collapsedIcon = UIManager.getIcon("Tree.collapsedIcon"); assert collapsedIcon != null: "no Tree.collapsedIcon found"; 1118 return collapsedIcon; 1119 } 1120 1121 1122 static Color getSetRendererColor() { 1123 if (setRendererColor == null) { 1124 deriveColorsAndMargin(); 1125 } 1126 1127 return setRendererColor; 1128 } 1129 1130 1131 static Color getSelectedSetRendererColor() { 1132 if (selectedSetRendererColor == null) { 1133 deriveColorsAndMargin(); 1134 } 1135 1136 return selectedSetRendererColor; 1137 } 1138 1139 1140 static Color getSetForegroundColor() { 1141 if (setForegroundColor == null) { 1142 deriveColorsAndMargin(); 1143 } 1144 1145 return setForegroundColor; 1146 } 1147 1148 1149 static Color getSelectedSetForegroundColor() { 1150 if (selectedSetForegroundColor == null) { 1151 deriveColorsAndMargin(); 1152 } 1153 1154 return selectedSetForegroundColor; 1155 } 1156 1157 1160 static int getMarginWidth() { 1161 if (marginWidth == -1) { 1162 deriveColorsAndMargin(); 1163 } 1164 1165 return marginWidth; 1166 } 1167 1168 1169 static int getSpinnerHeight() { 1170 if (spinnerHeight == -1) { 1171 deriveColorsAndMargin(); 1172 } 1173 1174 return spinnerHeight; 1175 } 1176 1177 1181 static int getIconMargin() { 1182 if (iconMargin == -1) { 1183 deriveColorsAndMargin(); 1184 } 1185 1186 return iconMargin; 1187 } 1188 1189 1190 static Icon getCustomButtonIcon() { 1191 return new BpIcon(); 1192 } 1193 1194 1198 private static int adjustColorComponent(int base, int adjBright, int adjDark) { 1199 if (base > 128) { 1200 base -= adjBright; 1201 } else { 1202 base += adjDark; 1203 } 1204 1205 if (base < 0) { 1206 base = 0; 1207 } 1208 1209 if (base > 255) { 1210 base = 255; 1211 } 1212 1213 return base; 1214 } 1215 1216 1219 static String basicPropsTabName() { 1220 if (bptn == null) { 1221 bptn = NbBundle.getMessage(PropUtils.class, "LBL_BasicTab"); } 1223 1224 return bptn; 1225 } 1226 1227 static Comparator getTabListComparator() { 1228 if (comp == null) { 1229 comp = new TabListComparator(); 1230 } 1231 1232 return comp; 1233 } 1234 1235 static SplitPaneUI createSplitPaneUI() { 1236 return new CleanSplitPaneUI(); 1237 } 1238 1239 static boolean shouldShowDescription() { 1240 return preferences().getBoolean(PREF_KEY_SHOWDESCRIPTION, true); 1241 } 1242 1243 static void saveShowDescription(boolean b) { 1244 preferences().putBoolean(PREF_KEY_SHOWDESCRIPTION, b); 1245 } 1246 1247 static String [] getSavedClosedSetNames() { 1248 String s = preferences().get(PREF_KEY_CLOSEDSETNAMES, null); 1249 1250 if (s != null) { 1251 StringTokenizer tok = new StringTokenizer(s, ","); String [] result = new String [tok.countTokens()]; 1253 int i = 0; 1254 1255 while (tok.hasMoreElements()) { 1256 result[i] = tok.nextToken(); 1257 i++; 1258 } 1259 1260 return result; 1261 } else { 1262 return new String [0]; 1263 } 1264 } 1265 1266 static void putSavedClosedSetNames(Set s) { 1267 if (s.size() > 0) { 1268 StringBuffer sb = new StringBuffer (s.size() * 20); 1269 Iterator i = s.iterator(); 1270 1271 while (i.hasNext()) { 1272 sb.append(i.next()); 1273 1274 if (i.hasNext()) { 1275 sb.append(','); } 1277 } 1278 1279 preferences().put(PREF_KEY_CLOSEDSETNAMES, sb.toString()); 1280 } else { 1281 preferences().put(PREF_KEY_CLOSEDSETNAMES, ""); 1282 } 1283 } 1284 1285 static void putSortOrder(int i) { 1286 preferences().putInt(PREF_KEY_SORTORDER, i); 1287 } 1288 1289 static int getSavedSortOrder() { 1290 return preferences().getInt(PREF_KEY_SORTORDER, PropertySheet.UNSORTED); 1291 } 1292 1293 1296 static int getTextMargin() { 1297 if ("apple.laf.AquaLookAndFeel".equals(UIManager.getLookAndFeel().getClass().getName())) { 1298 return 0; 1299 } 1300 1301 if (textMargin == -1) { 1302 Object o = UIManager.get("netbeans.ps.textMargin"); 1304 if (o instanceof Integer ) { 1305 textMargin = ((Integer ) o).intValue(); 1306 } else { 1307 textMargin = 2; 1308 } 1309 } 1310 1311 return textMargin; 1312 } 1313 1314 1315 static String createHtmlTooltip(String title, String s) { 1316 boolean wasHtml = false; 1317 1318 if (s.matches("\\<(html|HTML)\\>.*\\<\\/(html|HTML)\\>")) { s = s.replaceAll("\\<\\/{0,1}(html|HTML)\\>", ""); wasHtml = true; 1321 } 1322 1323 String token = null; 1325 1326 if (s.indexOf(" ") != -1) { token = " "; } else if (s.indexOf(",") != -1) { token = ","; } else if (s.indexOf(";") != -1) { token = ";"; } else if (s.indexOf("/") != -1) { token = "/"; } else if (s.indexOf("\\") != -1) { token = "\\"; } else { 1337 return s; 1339 } 1340 1341 StringTokenizer tk = new StringTokenizer(s, token, true); 1342 1343 StringBuffer sb = new StringBuffer (s.length() + 20); 1344 sb.append("<html>"); sb.append("<b><u>"); sb.append(title); 1347 sb.append("</u></b><br>"); 1349 int charCount = 0; 1350 int lineCount = 0; 1351 1352 while (tk.hasMoreTokens()) { 1353 String a = tk.nextToken(); 1354 1355 if (!wasHtml) { 1356 a = Utilities.replaceString(a, "&", "&"); a = Utilities.replaceString(a, "<", "<"); a = Utilities.replaceString(a, ">", ">"); } 1362 1363 charCount += a.length(); 1364 sb.append(a); 1365 1366 if (tk.hasMoreTokens()) { 1367 charCount++; 1368 } 1369 1370 if (charCount > 80) { 1371 sb.append("<br>"); charCount = 0; 1373 lineCount++; 1374 1375 if (lineCount > 10) { 1376 sb.append(NbBundle.getMessage(PropUtils.class, "MSG_ELLIPSIS")); 1381 return sb.toString(); 1382 } 1383 } 1384 } 1385 1386 sb.append("</html>"); 1388 return sb.toString(); 1389 } 1390 1391 1394 static InplaceEditor findInnermostInplaceEditor(InplaceEditor ine) { 1395 while (ine instanceof IconPanel || ine instanceof ButtonPanel) { 1396 if (ine instanceof IconPanel) { 1397 ine = ((IconPanel) ine).getInplaceEditor(); 1398 } else { 1399 ine = ((ButtonPanel) ine).getInplaceEditor(); 1400 } 1401 } 1402 1403 return ine; 1404 } 1405 1406 1410 static boolean shouldDrawMargin(PropertySetModel psm) { 1411 if (neverMargin) { 1412 return false; 1413 } 1414 1415 int setCount = psm.getSetCount(); 1419 1420 if (psm.getComparator() != null) { 1421 return false; 1422 } 1423 1424 boolean includeMargin = (setCount > 1) || (!((setCount == 1) && hideSingleExpansion)); 1425 1426 return includeMargin; 1427 } 1428 1429 1434 private static final Color getIconForeground() { 1435 return UIManager.getColor("PropSheet.customButtonForeground"); } 1437 1438 public static boolean isXPTheme() { 1439 Boolean isXP = (Boolean ) Toolkit.getDefaultToolkit().getDesktopProperty("win.xpstyle.themeActive"); 1440 1441 return (isXP == null) ? false : isXP.booleanValue(); 1442 } 1443 1444 1447 static final boolean shallBeRDVEnabled(FeatureDescriptor fd) { 1448 if ((fd != null) && fd instanceof Node.Property) { 1449 return shallBeRDVEnabled((Node.Property) fd); 1450 } 1451 1452 return false; 1453 } 1454 1455 1469 static final boolean shallBeRDVEnabled(Node.Property property) { 1470 if ((property == null) || !property.supportsDefaultValue()) { 1471 return false; 1472 } 1473 1474 try { 1475 if (property.getClass().getMethod("isDefaultValue").getDeclaringClass() == Node.Property.class) { 1476 return true; 1480 } else { 1481 return !property.isDefaultValue(); 1482 } 1483 } catch (NoSuchMethodException e) { 1484 assert false : "No isDefaultValue in " + property.getClass() + ": " + e; 1486 1487 return true; } 1489 } 1490 1491 static void addExternallyEdited(Property p) { 1492 externallyEdited.add(p); 1493 } 1494 1495 static void removeExternallyEdited(Property p) { 1496 externallyEdited.remove(p); 1497 } 1498 1499 static boolean isExternallyEdited(Property p) { 1500 return externallyEdited.contains(p); 1501 } 1502 1503 1505 static class DifferentValuesEditor implements PropertyEditor { 1506 protected PropertyEditor ed; 1507 private boolean notSet = true; 1508 1509 public DifferentValuesEditor(PropertyEditor ed) { 1510 this.ed = ed; 1511 addPropertyChangeListener(new PropertyChangeListener() { 1512 public void propertyChange(PropertyChangeEvent evt){ 1513 notSet=false; 1514 } 1515 }); 1516 } 1517 1518 public void addPropertyChangeListener(PropertyChangeListener listener) { 1519 ed.addPropertyChangeListener(listener); 1520 } 1521 1522 public String getAsText() { 1523 String result; 1524 1525 if (notSet) { 1526 result = NbBundle.getMessage(PropUtils.class, "CTL_Different_Values"); } else { 1528 result = ed.getAsText(); 1529 } 1530 1531 return result; 1532 } 1533 1534 public java.awt.Component getCustomEditor() { 1535 return ed.getCustomEditor(); 1536 } 1537 1538 public String getJavaInitializationString() { 1539 return ed.getJavaInitializationString(); 1540 } 1541 1542 public String [] getTags() { 1543 return ed.getTags(); 1544 } 1545 1546 public Object getValue() { 1547 Object result; 1548 1549 if (notSet) { 1550 result = null; 1551 } else { 1552 result = ed.getValue(); 1553 } 1554 1555 return result; 1556 } 1557 1558 public boolean isPaintable() { 1559 return notSet ? false : ed.isPaintable(); 1560 } 1561 1562 public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) { 1563 if (isPaintable()) { 1565 ed.paintValue(gfx, box); 1566 } 1567 } 1568 1569 public void removePropertyChangeListener(PropertyChangeListener listener) { 1570 ed.removePropertyChangeListener(listener); 1571 } 1572 1573 public void setAsText(String text) throws java.lang.IllegalArgumentException { 1574 ed.setAsText(text); 1575 notSet = false; 1576 } 1577 1578 public void setValue(Object value) { 1579 ed.setValue(value); 1580 notSet = false; 1581 } 1582 1583 public boolean supportsCustomEditor() { 1584 return ed.supportsCustomEditor(); 1585 } 1586 } 1587 1588 1592 static final class ExDifferentValuesEditor extends DifferentValuesEditor implements ExPropertyEditor{ 1593 1594 public ExDifferentValuesEditor(PropertyEditor ed){ 1595 super(ed); 1596 } 1597 1598 public void attachEnv(PropertyEnv env){ 1599 ((ExPropertyEditor)ed).attachEnv(env); 1600 } 1601 } 1602 1603 1604 1607 static final class NoPropertyEditorEditor implements PropertyEditor { 1608 public void addPropertyChangeListener(PropertyChangeListener listener) { 1609 } 1611 1612 public String getAsText() { 1613 return NbBundle.getMessage(PropertySheet.class, "CTL_NoPropertyEditor"); } 1615 1616 public java.awt.Component getCustomEditor() { 1617 return null; 1618 } 1619 1620 public String getJavaInitializationString() { 1621 return ""; 1622 } 1623 1624 public String [] getTags() { 1625 return null; 1626 } 1627 1628 public Object getValue() { 1629 return getAsText(); 1630 } 1631 1632 public boolean isPaintable() { 1633 return false; 1634 } 1635 1636 public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) { 1637 } 1639 1640 public void removePropertyChangeListener(PropertyChangeListener listener) { 1641 } 1643 1644 public void setAsText(String text) throws java.lang.IllegalArgumentException { 1645 } 1647 1648 public void setValue(Object value) { 1649 } 1651 1652 public boolean supportsCustomEditor() { 1653 return false; 1654 } 1655 } 1656 1657 1659 private static class TabListComparator implements Comparator { 1660 public int compare(Object o1, Object o2) { 1661 String s1 = (String ) o1; 1662 String s2 = (String ) o2; 1663 1664 if (s1 == s2) { 1665 return 0; 1666 } 1667 1668 String bn = basicPropsTabName(); 1669 1670 if (bn.equals(s1)) { 1671 return -1; 1672 } 1673 1674 if (bn.equals(s2)) { 1675 return 1; 1676 } 1677 1678 return s1.compareTo(s2); 1679 } 1680 } 1681 1682 private static class CleanSplitPaneUI extends BasicSplitPaneUI { 1683 protected void installDefaults() { 1684 super.installDefaults(); 1685 divider.setBorder(new SplitBorder()); 1686 } 1687 1688 public BasicSplitPaneDivider createDefaultDivider() { 1689 return new CleanSplitPaneDivider(this); 1690 } 1691 } 1692 1693 private static class CleanSplitPaneDivider extends BasicSplitPaneDivider implements Accessible { 1694 private AccessibleContext accessibleContext; 1695 1696 public CleanSplitPaneDivider( BasicSplitPaneUI ui ) { 1697 super( ui ); 1698 } 1699 public AccessibleContext getAccessibleContext() { 1700 if( null == accessibleContext ) { 1701 accessibleContext = new AccessibleAWTComponent() { 1702 public AccessibleRole getAccessibleRole() { 1703 return AccessibleRole.SPLIT_PANE; 1704 } 1705 }; 1706 1707 accessibleContext.setAccessibleName( NbBundle.getMessage(DescriptionComponent.class, "ACS_Splitter") ); 1708 accessibleContext.setAccessibleDescription( NbBundle.getMessage(DescriptionComponent.class, "ACSD_Splitter") ); 1709 } 1710 return accessibleContext; 1711 } 1712 } 1713 1714 1715 private static class SplitBorder implements Border { 1716 public Insets getBorderInsets(Component c) { 1717 if (UIManager.getLookAndFeel() instanceof MetalLookAndFeel) { 1718 return new Insets(2, 0, 1, 0); 1719 } else { 1720 return new Insets(1, 0, 1, 0); 1721 } 1722 } 1723 1724 public boolean isBorderOpaque() { 1725 return true; 1726 } 1727 1728 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 1729 if (UIManager.getLookAndFeel() instanceof MetalLookAndFeel) { 1730 g.setColor(UIManager.getColor("controlShadow")); 1731 g.drawLine(x, y, x + width, y); 1732 g.setColor(UIManager.getColor("controlHighlight")); 1733 g.drawLine(x, y + 1, x + width, y + 1); 1734 g.drawLine(x, (y + height) - 1, x + width, (y + height) - 1); 1735 g.setColor(UIManager.getColor("controlShadow")); 1736 g.drawLine(x, (y + height) - 2, x + width, (y + height) - 2); 1737 } else { 1738 g.setColor(UIManager.getColor("controlHighlight")); 1740 g.drawLine(x, y, x + width, y); 1741 g.setColor(UIManager.getColor("controlShadow")); 1742 g.drawLine(x, (y + height) - 1, x + width, (y + height) - 1); 1743 } 1744 } 1745 } 1746 1747 1749 static class BpIcon implements Icon { 1750 boolean larger; 1751 1752 public BpIcon() { 1753 Font f = UIManager.getFont("Table.font"); larger = (f != null) ? (f.getSize() > 13) : false; 1755 } 1756 1757 public int getIconHeight() { 1758 return 12; 1759 } 1760 1761 public int getIconWidth() { 1762 return larger ? 16 : 12; 1763 } 1764 1765 public void paintIcon(Component c, Graphics g, int x, int y) { 1766 int w = c.getWidth(); 1767 int h = c.getHeight(); 1768 int ybase = h - 5; 1769 int pos2 = (w / 2); 1770 int pos1 = pos2 - 4; 1771 int pos3 = pos2 + 4; 1772 g.setColor((getIconForeground() == null) ? c.getForeground() : getIconForeground()); 1773 drawDot(g, pos1 + 1, ybase, larger); 1774 drawDot(g, pos2, ybase, larger); 1775 drawDot(g, pos3 - 1, ybase, larger); 1776 } 1777 1778 private void drawDot(Graphics g, int x, int y, boolean larger) { 1779 if (!larger) { 1780 g.drawLine(x, y, x, y); 1781 } else { 1782 g.drawLine(x - 1, y, x + 1, y); 1783 g.drawLine(x, y - 1, x, y + 1); 1784 } 1785 } 1786 } 1787 1788} 1789 | Popular Tags |