1 7 package com.sun.java.swing.plaf.gtk; 8 9 import com.sun.java.swing.SwingUtilities2; 10 import javax.swing.plaf.synth.*; 11 import java.awt.*; 12 import java.awt.image.BufferedImage ; 13 import java.awt.image.RescaleOp ; 14 import java.lang.reflect.*; 15 import javax.swing.*; 16 import javax.swing.plaf.*; 17 import java.util.*; 18 import java.security.*; 19 20 import sun.swing.plaf.synth.*; 21 import sun.awt.AppContext; 22 23 30 public class GTKStyle extends DefaultSynthStyle implements GTKConstants { 31 private static final String ICON_PROPERTY_PREFIX = "gtk.icon."; 32 33 static final Color BLACK_COLOR = new ColorUIResource(Color.BLACK); 34 static final Color WHITE_COLOR = new ColorUIResource(Color.WHITE); 35 36 private static final Color[][] DEFAULT_COLORS; 37 41 private static final int[] DEFAULT_COLOR_MAP; 42 private static final Font DEFAULT_FONT = new FontUIResource( 45 "sansserif", Font.PLAIN, 10); 46 50 private static final HashMap DATA = new HashMap(); 54 55 59 private static final HashMap CLASS_SPECIFIC_MAP; 60 61 private static final GTKGraphicsUtils GTK_GRAPHICS =new GTKGraphicsUtils(); 62 63 66 static final int UNDEFINED_THICKNESS = -1; 67 68 private int xThickness = 2; 71 private int yThickness = 2; 72 73 79 private CircularIdentityList classSpecificValues; 80 81 84 private GTKStockIconInfo[] icons; 85 86 89 static Color calculateLightColor(Color bg) { 90 return GTKColorType.adjustColor(bg, 1.0f, 1.3f, 1.3f); 91 } 92 93 96 static Color calculateDarkColor(Color bg) { 97 return GTKColorType.adjustColor(bg, 1.0f, .7f, .7f); 98 } 99 100 103 static Color calculateMidColor(Color lightColor, Color darkColor) { 104 int light = lightColor.getRGB(); 105 int dark = darkColor.getRGB(); 106 int rLight = (light & 0xFF0000) >> 16; 107 int rDark = (dark & 0xFF0000) >> 16; 108 int gLight = (light & 0x00FF00) >> 8; 109 int gDark = (dark & 0x00FF00) >> 8; 110 int bLight = (light & 0xFF); 111 int bDark = (dark & 0xFF); 112 return new ColorUIResource((((rLight + rDark) / 2) << 16) | 113 (((gLight + gDark) / 2) << 8) | 114 ((bLight + bDark) / 2)); 115 } 116 117 120 static Color calculateMidColor(Color bg) { 121 return calculateMidColor(calculateLightColor(bg), 122 calculateDarkColor(bg)); 123 } 124 125 131 static Color[] getColorsFrom(Color bg, Color fg) { 132 Color lightColor = calculateLightColor(bg); 133 Color darkColor = calculateDarkColor(bg); 134 Color midColor = calculateMidColor(lightColor, darkColor); 135 Color[] colors = new Color[GTKColorType.MAX_COUNT]; 136 colors[GTKColorType.BACKGROUND.getID()] = bg; 137 colors[GTKColorType.LIGHT.getID()] = lightColor; 138 colors[GTKColorType.DARK.getID()] = darkColor; 139 colors[GTKColorType.MID.getID()] = midColor; 140 colors[GTKColorType.BLACK.getID()] = BLACK_COLOR; 141 colors[GTKColorType.WHITE.getID()] = WHITE_COLOR; 142 colors[GTKColorType.FOCUS.getID()] = BLACK_COLOR; 143 colors[GTKColorType.FOREGROUND.getID()] = fg; 144 colors[GTKColorType.TEXT_FOREGROUND.getID()] = fg; 145 colors[GTKColorType.TEXT_BACKGROUND.getID()] = WHITE_COLOR; 146 return colors; 147 } 148 149 152 public GTKStyle(DefaultSynthStyle style) { 153 super(style); 154 if (style instanceof GTKStyle) { 155 GTKStyle gStyle = (GTKStyle)style; 156 xThickness = gStyle.xThickness; 157 yThickness = gStyle.yThickness; 158 icons = gStyle.icons; 159 classSpecificValues = cloneClassSpecificValues( 160 gStyle.classSpecificValues); 161 } 162 } 163 164 167 public GTKStyle() { 168 super(new Insets(-1, -1, -1, -1), true, null, null); 169 } 170 171 176 public GTKStyle(Font font) { 177 this(); 178 setFont(font); 179 } 180 181 193 GTKStyle(StateInfo[] states, 194 CircularIdentityList classSpecificValues, 195 Font font, 196 int xThickness, int yThickness, 197 GTKStockIconInfo[] icons) { 198 super(new Insets(-1, -1, -1, -1), true, states, null); 199 setFont(font); 200 this.xThickness = xThickness; 201 this.yThickness = yThickness; 202 this.icons = icons; 203 this.classSpecificValues = classSpecificValues; 204 } 205 206 209 public void installDefaults(SynthContext context) { 210 super.installDefaults(context); 211 if (!context.getRegion().isSubregion()) { 212 context.getComponent().putClientProperty( 213 SwingUtilities2.AA_TEXT_PROPERTY_KEY, 214 GTKLookAndFeel.aaText); 215 } 216 } 217 218 public SynthGraphicsUtils getGraphicsUtils(SynthContext context) { 219 return GTK_GRAPHICS; 220 } 221 222 228 public GTKEngine getEngine(SynthContext context) { 229 GTKEngine engine = (GTKEngine)get(context, "engine"); 230 231 if (engine == null) { 232 return GTKEngine.INSTANCE; 233 } 234 return engine; 235 } 236 237 244 public SynthPainter getPainter(SynthContext state) { 245 return GTKPainter.INSTANCE; 246 } 247 248 257 public Insets getInsets(SynthContext state, Insets insets) { 258 insets = super.getInsets(state, insets); 259 260 if (insets.top == -1) { 261 insets.left = insets.right = insets.top = insets.bottom = 0; 262 insets = GTKPainter.INSTANCE.getInsets(state, insets); 263 } 264 return insets; 265 } 266 267 282 public Object getClassSpecificValue(Region region, String key) { 283 if (classSpecificValues != null) { 284 String gtkClass = GTKStyleFactory.gtkClassFor(region); 285 286 while (gtkClass != null) { 287 CircularIdentityList classValues = (CircularIdentityList) 288 classSpecificValues.get(gtkClass); 289 290 if (classValues != null) { 291 Object value = classValues.get(key); 292 293 if (value != null) { 294 return value; 295 } 296 } 297 gtkClass = GTKStyleFactory.gtkSuperclass(gtkClass); 298 } 299 } 300 return null; 301 } 302 303 318 public Object getClassSpecificValue(SynthContext context, String key) { 319 return getClassSpecificValue(context.getRegion(), key); 320 } 321 322 331 public int getClassSpecificIntValue(SynthContext context, String key, 332 int defaultValue) { 333 Object value = getClassSpecificValue(context, key); 334 335 if (value instanceof Number ) { 336 return ((Number )value).intValue(); 337 } 338 return defaultValue; 339 } 340 341 350 public Insets getClassSpecificInsetsValue(SynthContext context, String key, 351 Insets defaultValue) { 352 Object value = getClassSpecificValue(context, key); 353 354 if (value instanceof Insets) { 355 return (Insets)value; 356 } 357 return defaultValue; 358 } 359 360 369 public boolean getClassSpecificBoolValue(SynthContext context, String key, 370 boolean defaultValue) { 371 Object value = getClassSpecificValue(context, key); 372 373 if (value instanceof Boolean ) { 374 return ((Boolean )value).booleanValue(); 375 } 376 return defaultValue; 377 } 378 379 public Object getDefaultValue(SynthContext context, Object key) { 380 Object classKey = CLASS_SPECIFIC_MAP.get(key); 382 Object value = null; 383 384 if (classKey != null) { 385 value = getClassSpecificValue(context, (String )classKey); 386 if (value != null) { 387 return value; 388 } 389 } 390 391 if (key == "ScrollPane.viewportBorderInsets") { 392 return GTKPainter.INSTANCE.getScrollPaneInsets(context, 393 new Insets(0,0,0,0)); 394 } else if (key == "Slider.tickColor") { 395 return getColor(context.getComponent(), context.getRegion(), 396 context.getComponentState(), ColorType.FOREGROUND); 397 } 398 synchronized (DATA) { 399 value = DATA.get(key); 400 } 401 if (value instanceof StyleSpecificValue) { 402 put(key, ((StyleSpecificValue)value).getValue(context)); 403 } 404 if (value == null && key != "engine") { 405 value = UIManager.get(key); 409 if (key == "Table.rowHeight") { 410 int focusLineWidth = getClassSpecificIntValue( 411 context, "focus-line-width", 0); 412 if (value == null && focusLineWidth > 0) { 413 value = new Integer (16 + 2 * focusLineWidth); 414 } 415 } 416 } 417 return value; 420 } 421 422 431 protected Font getFontForState(JComponent c, Region id, int state) { 432 state = GTKLookAndFeel.synthStateToGTKState(id, state); 433 434 Font f = super.getFontForState(c, id, state); 435 436 if (f == null) { 437 return DEFAULT_FONT; 438 } 439 return f; 440 } 441 442 Color getGTKColor(int state, ColorType type) { 443 return getGTKColor(null, null, state, type); 444 } 445 446 457 public Color getGTKColor(JComponent c, Region id, 458 int state, ColorType type) { 459 if (c != null && id != null) { 462 if (!id.isSubregion() && 463 (state & SynthConstants.ENABLED) == SynthConstants.ENABLED) { 464 if (type == ColorType.BACKGROUND) { 465 Color bg = c.getBackground(); 466 if (!(bg instanceof UIResource)) { 467 return bg; 468 } 469 } 470 else if (type == ColorType.FOREGROUND) { 471 Color fg = c.getForeground(); 472 if (!(fg instanceof UIResource)) { 473 return fg; 474 } 475 } 476 else if (type == ColorType.TEXT_FOREGROUND) { 477 Color fg = c.getForeground(); 478 if (!(fg instanceof UIResource)) { 479 return fg; 480 } 481 } 482 else if (type == ColorType.TEXT_BACKGROUND) { 483 Color bg = c.getBackground(); 484 if (!(bg instanceof UIResource)) { 485 return bg; 486 } 487 } 488 } 489 } 490 Color color = super.getColorForState(c, id, state, type); 491 if (color != null) { 492 return color; 493 } 494 return getDefaultColor(c, id, state, type); 495 } 496 497 509 public Color getColor(JComponent c, Region id, int state, 510 ColorType type) { 511 if (id == Region.LABEL && type == ColorType.TEXT_FOREGROUND) { 512 type = ColorType.FOREGROUND; 513 } 514 state = GTKLookAndFeel.synthStateToGTKState(id, state); 515 if (!id.isSubregion() && 516 (state & SynthConstants.ENABLED) == SynthConstants.ENABLED) { 517 if (type == ColorType.BACKGROUND) { 518 return c.getBackground(); 519 } 520 else if (type == ColorType.FOREGROUND) { 521 return c.getForeground(); 522 } 523 else if (type == ColorType.TEXT_FOREGROUND) { 524 Color fg = c.getForeground(); 525 if (fg != null && !(fg instanceof UIResource)) { 526 return fg; 528 } 529 } 530 } 531 return getColorForState(c, id, state, type); 532 } 533 534 545 protected Color getColorForState(JComponent c, Region id, int state, 546 ColorType type) { 547 Color color = super.getColorForState(c, id, state, type); 548 549 if (color != null) { 550 return color; 551 } 552 if (type == ColorType.FOCUS) { 553 return BLACK_COLOR; 554 } 555 else if (type == GTKColorType.BLACK) { 556 return BLACK_COLOR; 557 } 558 else if (type == GTKColorType.WHITE) { 559 return WHITE_COLOR; 560 } 561 if (type == ColorType.TEXT_FOREGROUND && (GTKStyleFactory. 562 isLabelBearing(id) || id == Region.MENU_ITEM_ACCELERATOR || 563 id == Region.TABBED_PANE_TAB)) { 564 type = ColorType.FOREGROUND; 565 } 566 else if (id == Region.TABLE || id == Region.LIST || 567 id == Region.TREE || id == Region.TREE_CELL){ 568 if (type == ColorType.FOREGROUND) { 569 type = ColorType.TEXT_FOREGROUND; 570 if (state == SynthConstants.PRESSED) { 571 state = SynthConstants.SELECTED; 572 } 573 } 574 else if (type == ColorType.BACKGROUND) { 575 type = ColorType.TEXT_BACKGROUND; 576 if (state == SynthConstants.PRESSED) { 577 state = SynthConstants.SELECTED; 578 } 579 } 580 } 581 return getDefaultColor(c, id, state, type); 582 } 583 584 593 Color getDefaultColor(JComponent c, Region id, int state, 594 ColorType type) { 595 if (type == ColorType.FOCUS) { 596 return BLACK_COLOR; 597 } 598 else if (type == GTKColorType.BLACK) { 599 return BLACK_COLOR; 600 } 601 else if (type == GTKColorType.WHITE) { 602 return WHITE_COLOR; 603 } 604 for (int counter = DEFAULT_COLOR_MAP.length - 1; 605 counter >= 0; counter--) { 606 if ((DEFAULT_COLOR_MAP[counter] & state) != 0) { 607 if (type.getID() < DEFAULT_COLORS[counter].length) { 608 return DEFAULT_COLORS[counter][type.getID()]; 609 } 610 } 611 } 612 if (type.getID() < DEFAULT_COLORS[2].length) { 613 return DEFAULT_COLORS[2][type.getID()]; 614 } 615 return null; 616 } 617 618 626 public boolean isOpaque(SynthContext context) { 627 Region region = context.getRegion(); 628 if (region == Region.COMBO_BOX || 629 region == Region.DESKTOP_PANE || 630 region == Region.DESKTOP_ICON || 631 region == Region.EDITOR_PANE || 632 region == Region.FORMATTED_TEXT_FIELD || 633 region == Region.INTERNAL_FRAME || 634 region == Region.LIST || 635 region == Region.MENU_BAR || 636 region == Region.PASSWORD_FIELD || 637 region == Region.POPUP_MENU || 638 region == Region.PROGRESS_BAR || 639 region == Region.ROOT_PANE || 640 region == Region.SCROLL_PANE || 641 region == Region.SPINNER || 642 region == Region.TABLE || 643 region == Region.TEXT_AREA || 644 region == Region.TEXT_FIELD || 645 region == Region.TEXT_PANE || 646 region == Region.TOOL_BAR_DRAG_WINDOW || 647 region == Region.TOOL_TIP || 648 region == Region.TREE || 649 region == Region.VIEWPORT) { 650 return true; 651 } 652 Component c = context.getComponent(); 653 String name = c.getName(); 654 if (name == "ComboBox.renderer" || name == "ComboBox.listRenderer") { 655 return true; 656 } 657 return false; 658 } 659 660 665 public int getXThickness() { 666 return xThickness; 667 } 668 669 674 public int getYThickness() { 675 return yThickness; 676 } 677 678 private Icon getStockIcon(SynthContext context, String key, int type) { 679 Icon icon = null; 680 GTKStockIconInfo iconInfo = null; 681 GTKIconSource bestSource = null; 682 int direction = LTR; 683 684 if (context != null) { 685 ComponentOrientation co = context.getComponent(). 686 getComponentOrientation(); 687 688 if (co == null || co.isLeftToRight()) { 689 direction = LTR; 690 } 691 else { 692 direction = RTL; 693 } 694 } 695 if (icons != null) { 697 for (int i = 0; i < icons.length; i++) { 698 if (icons[i].getKey() == key) { 700 iconInfo = icons[i]; 701 break; 702 } 703 } 704 705 if (iconInfo != null) { 706 bestSource = iconInfo.getBestIconSource(direction, 708 SynthConstants.ENABLED, 709 type); 710 } 711 712 if (bestSource != null) { 713 icon = bestSource.toIcon(); 714 } 715 } 716 717 if (icon == null) { 718 String propName = ICON_PROPERTY_PREFIX + key + '.' + type + '.' + 720 (direction == RTL ? "rtl" : "ltr"); 721 Image img = (Image )Toolkit.getDefaultToolkit(). 722 getDesktopProperty(propName); 723 if (img != null) { 724 icon = new ImageIcon(img); 725 return icon; 726 } else { 727 icon = (Icon)((UIDefaults.LazyValue)LookAndFeel.makeIcon( 728 GTKStyle.class, "resources/" + key + "-" + type + 729 ".png")).createValue(null); 730 } 731 } 732 733 if (icon == null) { 734 return null; 735 } 736 BufferedImage image = null; 737 738 if (bestSource == null || bestSource.getSize() == UNDEFINED) { 741 Dimension iconSize = GTKStockIconInfo.getIconSize(type); 742 743 if (iconSize != null && (icon.getIconWidth() != iconSize.width || 744 icon.getIconHeight() != iconSize.height)) { 745 image = new BufferedImage (iconSize.width, iconSize.height, 746 BufferedImage.TYPE_INT_ARGB); 747 748 Graphics2D g2d = (Graphics2D)image.getGraphics(); 749 750 g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 752 RenderingHints.VALUE_INTERPOLATION_BILINEAR); 753 754 Image oldImage = getImageFromIcon(icon, false); 755 g2d.drawImage(oldImage, 0, 0, iconSize.width, iconSize.height, null); 756 g2d.dispose(); 757 } 758 } 759 779 if (image != null) { 780 icon = new ImageIcon(image); 781 } 782 return icon; 783 } 784 785 private Image getImageFromIcon(Icon icon, boolean requireBufferedImage) { 786 Image img = null; 787 788 if (icon instanceof ImageIcon) { 789 img = ((ImageIcon)icon).getImage(); 790 if (requireBufferedImage && !(img instanceof BufferedImage )) { 791 img = null; 792 } 793 } 794 if (img == null) { 795 img = new BufferedImage (icon.getIconWidth(), icon.getIconHeight(), 796 BufferedImage.TYPE_INT_ARGB); 797 Graphics g = img.getGraphics(); 798 icon.paintIcon(null, g, 0, 0); 799 g.dispose(); 800 } 801 return img; 802 } 803 804 808 void addLabelProperties(GTKStyle style) { 809 StateInfo[] states = getStateInfo(); 810 StateInfo[] oStates = style.getStateInfo(); 811 setFont(style.getFontForState(null, null, 0)); 813 if (states == null) { 815 if (oStates == null) { 816 return; 817 } 818 states = new StateInfo[oStates.length]; 819 for (int counter = 0; counter < oStates.length; counter++) { 820 Color color = oStates[counter].getColor( 821 GTKColorType.FOREGROUND); 822 823 states[counter] = createStateInfo(oStates[counter]. 824 getComponentState(), GTKColorType.TEXT_FOREGROUND, color); 825 } 826 } 827 else { 828 for (int counter = states.length - 1; counter >= 0; counter--) { 832 ((GTKStateInfo)states[counter]).setColor( 833 GTKColorType.TEXT_FOREGROUND, null); 834 } 835 if (oStates != null) { 836 for (int oCounter = oStates.length - 1; oCounter >= 0; 837 oCounter--) { 838 boolean matched = false; 839 StateInfo oState = oStates[oCounter]; 840 int componentState = oState.getComponentState(); 841 Color color = oState.getColor(GTKColorType.FOREGROUND); 842 843 for (int tCounter = states.length - 1; tCounter >= 0; 844 tCounter--) { 845 if (componentState == states[tCounter]. 846 getComponentState()) { 847 ((GTKStateInfo)states[tCounter]).setColor( 848 GTKColorType.TEXT_FOREGROUND, color); 849 matched = true; 850 break; 851 } 852 } 853 if (!matched) { 854 StateInfo[] newStates = new StateInfo[states.length+1]; 855 System.arraycopy(states, 0, newStates, 0, 856 states.length); 857 newStates[states.length] = createStateInfo( 858 componentState, GTKColorType.TEXT_FOREGROUND, 859 color); 860 states = newStates; 861 } 862 } 863 } 864 } 865 } 866 867 872 GTKStateInfo createStateInfo(int state, ColorType type, Color color) { 873 Color[] colors = new Color[GTKColorType.MAX_COUNT]; 874 875 colors[type.getID()] = color; 876 return new GTKStateInfo(state, null, colors, null); 877 } 878 879 882 void put(Object key, Object value) { 883 Map data = getData(); 884 if (data== null) { 885 data = new HashMap(); 886 setData(data); 887 } 888 data.put(key, value); 889 } 890 891 895 boolean fillBackground(SynthContext context, int state) { 896 GTKStateInfo info = (GTKStateInfo)getStateInfo(state); 897 898 if (info != null) { 899 Object backgroundImage = info.getBackgroundImage(); 900 901 if (backgroundImage == "<none>" || backgroundImage == null) { 902 return true; 903 } 904 return false; 905 } 906 return true; 907 } 908 909 913 Image getBackgroundImage(SynthContext context, int state) { 914 GTKStateInfo info = (GTKStateInfo)getStateInfo(state); 915 916 if (info != null) { 917 Object backgroundImage = info.getBackgroundImage(); 918 919 if (backgroundImage instanceof Image ) { 920 return (Image )backgroundImage; 921 } 922 } 923 return null; 924 } 925 926 931 public Object clone() { 932 GTKStyle style = (GTKStyle)super.clone(); 933 934 style.classSpecificValues = cloneClassSpecificValues( 935 style.classSpecificValues); 936 return style; 937 } 938 939 950 public DefaultSynthStyle addTo(DefaultSynthStyle style) { 951 if (!(style instanceof GTKStyle)) { 952 style = new GTKStyle(style); 953 } 954 GTKStyle gtkStyle = (GTKStyle)super.addTo(style); 955 if (xThickness != UNDEFINED_THICKNESS) { 956 gtkStyle.xThickness = xThickness; 957 } 958 if (yThickness != UNDEFINED_THICKNESS) { 959 gtkStyle.yThickness = yThickness; 960 } 961 if (gtkStyle.icons == null) { 962 gtkStyle.icons = icons; 963 } 964 else if (icons != null) { 965 GTKStockIconInfo[] mergedIcons = 966 new GTKStockIconInfo[gtkStyle.icons.length + icons.length]; 967 968 System.arraycopy(icons, 0, mergedIcons, 0, icons.length); 969 System.arraycopy(gtkStyle.icons, 0, mergedIcons, icons.length, gtkStyle.icons.length); 970 971 gtkStyle.icons = mergedIcons; 972 } 973 974 if (gtkStyle.classSpecificValues == null) { 975 gtkStyle.classSpecificValues = 976 cloneClassSpecificValues(classSpecificValues); 977 } else { 978 addClassSpecificValues(classSpecificValues, gtkStyle.classSpecificValues); 979 } 980 981 return gtkStyle; 982 } 983 984 990 static void addClassSpecificValues(CircularIdentityList from, 991 CircularIdentityList to) { 992 if (to == null) { 993 throw new IllegalArgumentException ("to may not be null"); 994 } 995 996 if (from == null) { 997 return; 998 } 999 1000 synchronized(from) { 1001 Object firstKey = from.next(); 1002 if (firstKey != null) { 1003 Object key = firstKey; 1004 do { 1005 CircularIdentityList cList = ((CircularIdentityList) 1006 from.get()); 1007 CircularIdentityList oSublist = (CircularIdentityList) 1008 to.get(key); 1009 if (oSublist == null) { 1010 to.set(key, cList.clone()); 1011 } 1012 else { 1013 Object cFirstKey = cList.next(); 1014 1015 if (cFirstKey != null) { 1016 Object cKey = cFirstKey; 1017 do { 1018 oSublist.set(cKey, cList.get()); 1019 cKey = cList.next(); 1020 } while (cKey != cFirstKey); 1021 } 1022 } 1023 key = from.next(); 1024 } while (key != firstKey); 1025 } 1026 } 1027 } 1028 1029 1032 static CircularIdentityList cloneClassSpecificValues( 1033 CircularIdentityList list) { 1034 if (list == null) { 1035 return null; 1036 } 1037 CircularIdentityList clone; 1038 synchronized(list) { 1039 Object firstKey = list.next(); 1040 if (firstKey == null) { 1041 return null; 1043 } 1044 clone = new CircularIdentityList(); 1045 Object key = firstKey; 1046 do { 1047 clone.set(key, ((CircularIdentityList)list.get()).clone()); 1048 key = list.next(); 1049 } while (key != firstKey); 1050 } 1051 return clone; 1052 } 1053 1054 1059 static class GTKStockIconInfo { 1060 private String key; 1061 private GTKIconSource[] sources; 1062 private static Map<String ,Integer > ICON_TYPE_MAP; 1063 private static final Object ICON_SIZE_KEY = new StringBuffer ("IconSize"); 1064 1065 GTKStockIconInfo(String key, GTKIconSource[] sources) { 1066 this.key = key.intern(); 1067 this.sources = sources; 1068 Arrays.sort(this.sources); 1069 } 1070 1071 public String getKey() { 1072 return key; 1073 } 1074 1075 public GTKIconSource getBestIconSource(int direction, int state, int size) { 1076 for (int i = 0; i < sources.length; i++) { 1077 GTKIconSource src = sources[i]; 1078 1079 if ((src.direction == UNDEFINED || src.direction == direction) 1080 && (src.state == UNDEFINED || src.state == state) 1081 && (src.size == UNDEFINED || src.size == size)) { 1082 return src; 1083 } 1084 } 1085 1086 return null; 1087 } 1088 1089 public String toString() { 1090 StringBuffer buf = new StringBuffer ("STOCK ICON " + key + ":\n"); 1091 1092 for (int i = 0; i < sources.length; i++) { 1093 buf.append(" ").append(sources[i].toString()).append('\n'); 1094 } 1095 1096 buf.deleteCharAt(buf.length() - 1); 1098 1099 return buf.toString(); 1100 } 1101 1102 1109 public static int getIconType(String size) { 1110 if (size == null) { 1111 return UNDEFINED; 1112 } 1113 if (ICON_TYPE_MAP == null) { 1114 initIconTypeMap(); 1115 } 1116 Integer n = ICON_TYPE_MAP.get(size); 1117 return n != null ? n.intValue() : UNDEFINED; 1118 } 1119 1120 private static void initIconTypeMap() { 1121 ICON_TYPE_MAP = new HashMap<String ,Integer >(); 1122 ICON_TYPE_MAP.put("gtk-menu", new Integer (1)); 1123 ICON_TYPE_MAP.put("gtk-small-toolbar", new Integer (2)); 1124 ICON_TYPE_MAP.put("gtk-large-toolbar", new Integer (3)); 1125 ICON_TYPE_MAP.put("gtk-button", new Integer (4)); 1126 ICON_TYPE_MAP.put("gtk-dnd", new Integer (5)); 1127 ICON_TYPE_MAP.put("gtk-dialog", new Integer (6)); 1128 } 1129 1130 1136 public static Dimension getIconSize(int type) { 1137 Dimension[] iconSizes = getIconSizesMap(); 1138 return type >= 0 && type < iconSizes.length ? 1139 iconSizes[type] : null; 1140 } 1141 1142 1150 public static void setIconSize(int type, int w, int h) { 1151 Dimension[] iconSizes = getIconSizesMap(); 1152 if (type >= 0 && type < iconSizes.length) { 1153 iconSizes[type] = new Dimension(w, h); 1154 } 1155 } 1156 1157 private static Dimension[] getIconSizesMap() { 1158 AppContext appContext = AppContext.getAppContext(); 1159 Dimension[] iconSizes = (Dimension[])appContext.get(ICON_SIZE_KEY); 1160 1161 if (iconSizes == null) { 1162 iconSizes = new Dimension[7]; 1163 iconSizes[0] = null; iconSizes[1] = new Dimension(16, 16); iconSizes[2] = new Dimension(18, 18); iconSizes[3] = new Dimension(24, 24); iconSizes[4] = new Dimension(20, 20); iconSizes[5] = new Dimension(32, 32); iconSizes[6] = new Dimension(48, 48); appContext.put(ICON_SIZE_KEY, iconSizes); 1171 } 1172 return iconSizes; 1173 } 1174 } 1175 1176 1177 1182 static class GTKIconSource implements Comparable { 1183 private Object image; 1184 private int direction; 1185 private int state; 1186 private int size; 1187 1188 GTKIconSource(String image, int direction, int state, String size) { 1189 this.image = image; 1190 this.direction = direction; 1191 this.state = state; 1192 1193 this.size = GTKStockIconInfo.getIconType(size); 1194 } 1195 1196 public int getDirection() { 1197 return direction; 1198 } 1199 1200 public int getState() { 1201 return state; 1202 } 1203 1204 public int getSize() { 1205 return size; 1206 } 1207 1208 public int compareTo(Object o) { 1209 GTKIconSource other = (GTKIconSource)o; 1210 1211 if (direction != UNDEFINED && other.direction == UNDEFINED) { 1212 return -1; 1213 } else if (direction == UNDEFINED && other.direction != UNDEFINED) { 1214 return 1; 1215 } else if (state != UNDEFINED && other.state == UNDEFINED) { 1216 return -1; 1217 } else if (state == UNDEFINED && other.state != UNDEFINED) { 1218 return 1; 1219 } else if (size != UNDEFINED && other.size == UNDEFINED) { 1220 return -1; 1221 } else if (size == UNDEFINED && other.size != UNDEFINED) { 1222 return 1; 1223 } else { 1224 return 0; 1225 } 1226 } 1227 1228 public String toString() { 1229 return "image=" + image + ", dir=" + getDirectionName(direction) 1230 + ", state=" + getStateName(state, "*") 1231 + ", size=" + (size == UNDEFINED ? "*" : ""+size); 1232 } 1233 1234 private static String getDirectionName(int dir) { 1236 switch(dir) { 1237 case LTR: return "LTR"; 1238 case RTL: return "RTL"; 1239 case UNDEFINED: return "*"; 1240 } 1241 1242 return "UNKNOWN"; 1243 } 1244 1245 public Icon toIcon() { 1246 if (image == null || image instanceof Icon) { 1247 return (Icon)image; 1248 } 1249 1250 ImageIcon ii = (ImageIcon)AccessController.doPrivileged(new PrivilegedAction() { 1251 public Object run() { 1252 return new ImageIcon((String )image); 1253 } 1254 }); 1255 1256 if (ii.getIconWidth() > 0 && ii.getIconHeight() > 0) { 1257 image = ii; 1258 } else { 1259 image = null; 1262 } 1263 1264 return (Icon)image; 1265 } 1266 } 1267 1268 public String toString() { 1269 StringBuffer buf = new StringBuffer (super.toString()); 1270 1271 if (xThickness != UNDEFINED_THICKNESS) { 1272 buf.append("xt=").append(String.valueOf(xThickness)).append('\n'); 1273 } 1274 1275 if (yThickness != UNDEFINED_THICKNESS) { 1276 buf.append("yt=").append(String.valueOf(yThickness)).append('\n'); 1277 } 1278 1279 if (classSpecificValues != null) { 1280 buf.append("*** Properties ***\n"); 1281 buf.append(classSpecValsToString(classSpecificValues)).append('\n'); 1282 } 1283 1284 if (icons != null) { 1285 buf.append("*** Stock Icons ***\n"); 1286 for (int i = 0; i < icons.length; i++) { 1287 buf.append(icons[i].toString()).append('\n'); 1288 } 1289 } 1290 1291 buf.deleteCharAt(buf.length() - 1); 1293 1294 return buf.toString(); 1295 } 1296 1297 private static String classSpecValsToString(CircularIdentityList parent) { 1299 StringBuffer buf = new StringBuffer (); 1300 1301 Object parentFirst = parent.next(); 1302 1303 if (parentFirst == null) { 1304 return ""; 1305 } 1306 1307 Object parentKey = parentFirst; 1308 1309 do { 1310 buf.append(parentKey).append('\n'); 1311 1312 CircularIdentityList child = (CircularIdentityList)parent.get(); 1313 1314 Object childFirst = child.next(); 1315 1316 if (childFirst == null) { 1317 break; 1318 } 1319 1320 Object childKey = childFirst; 1321 1322 do { 1323 buf.append(" ").append(childKey).append('=').append(child.get()).append('\n'); 1324 childKey = child.next(); 1325 } while (childKey != childFirst); 1326 1327 parentKey = parent.next(); 1328 } while (parentKey != parentFirst); 1329 1330 buf.deleteCharAt(buf.length() - 1); 1332 1333 return buf.toString(); 1334 } 1335 1336 1339 public static class GTKStateInfo extends StateInfo { 1340 private Object backgroundImage; 1344 1345 1354 public GTKStateInfo(int state, Font font, Color[] colors, 1355 Object backgroundImage) { 1356 super(state, font, colors); 1357 this.backgroundImage = backgroundImage; 1358 } 1359 1360 1366 public GTKStateInfo(StateInfo info) { 1367 super(info); 1368 if (info instanceof GTKStateInfo) { 1369 backgroundImage = ((GTKStateInfo)info).backgroundImage; 1370 } 1371 } 1372 1373 void setColor(ColorType type, Color color) { 1374 Color[] colors = getColors(); 1375 if (colors == null) { 1376 if (color == null) { 1377 return; 1378 } 1379 colors = new Color[GTKColorType.MAX_COUNT]; 1380 setColors(colors); 1381 } 1382 colors[type.getID()] = color; 1383 } 1384 1385 1390 public Color getColor(ColorType type) { 1391 Color color = super.getColor(type); 1392 1393 if (color == null) { 1394 Color[] colors = getColors(); 1395 Color bg; 1396 1397 if (colors != null && (bg = super.getColor( 1398 GTKColorType.BACKGROUND)) != null) { 1399 if (type == GTKColorType.LIGHT) { 1400 color = colors[GTKColorType.LIGHT.getID()] = 1401 calculateLightColor(bg); 1402 } 1403 else if (type == GTKColorType.MID) { 1404 color = colors[GTKColorType.MID.getID()] = 1405 calculateMidColor(bg); 1406 } 1407 else if (type == GTKColorType.DARK) { 1408 color = colors[GTKColorType.DARK.getID()] = 1409 calculateDarkColor(bg); 1410 } 1411 } 1412 } 1413 return color; 1414 } 1415 1416 1422 Object getBackgroundImage() { 1423 if (backgroundImage == null || 1424 (backgroundImage instanceof Image ) || 1425 backgroundImage == "<none>" || 1426 backgroundImage == "<parent>") { 1427 return backgroundImage; 1428 } 1429 1430 ImageIcon ii = (ImageIcon)AccessController.doPrivileged(new PrivilegedAction() { 1431 public Object run() { 1432 return new ImageIcon((String )backgroundImage); 1433 } 1434 }); 1435 1436 if (ii.getIconWidth() > 0 && ii.getIconHeight() > 0) { 1437 backgroundImage = ii.getImage(); 1438 } else { 1439 backgroundImage = null; 1440 } 1441 1442 return backgroundImage; 1443 } 1444 1445 1450 public Object clone() { 1451 return new GTKStateInfo(this); 1452 } 1453 1454 1467 public StateInfo addTo(StateInfo info) { 1468 if (!(info instanceof GTKStateInfo)) { 1469 info = new GTKStateInfo(info); 1470 } 1471 else { 1472 super.addTo(info); 1473 } 1474 GTKStateInfo gInfo = (GTKStateInfo)info; 1475 1476 if (backgroundImage != null) { 1477 gInfo.backgroundImage = backgroundImage; 1478 } 1479 return gInfo; 1480 } 1481 1482 public String toString() { 1483 StringBuffer buf = new StringBuffer (); 1484 1485 buf.append(getStateName(getComponentState(), "UNDEFINED")).append(":\n"); 1486 1487 if (getColor(GTKColorType.FOREGROUND) != null) { 1488 buf.append(" fg=").append(getColor(GTKColorType.FOREGROUND)).append('\n'); 1489 } 1490 1491 if (getColor(GTKColorType.BACKGROUND) != null) { 1492 buf.append(" bg=").append(getColor(GTKColorType.BACKGROUND)).append('\n'); 1493 } 1494 1495 if (getColor(GTKColorType.TEXT_FOREGROUND) != null) { 1496 buf.append(" text=").append(getColor(GTKColorType.TEXT_FOREGROUND)).append('\n'); 1497 } 1498 1499 if (getColor(GTKColorType.TEXT_BACKGROUND) != null) { 1500 buf.append(" base=").append(getColor(GTKColorType.TEXT_BACKGROUND)).append('\n'); 1501 } 1502 1503 if (backgroundImage != null) { 1504 buf.append(" pmn=").append(backgroundImage).append('\n'); 1505 } 1506 1507 buf.deleteCharAt(buf.length() - 1); 1509 1510 return buf.toString(); 1511 } 1512 } 1513 1514 static String getStateName(int state, String undef) { 1516 switch(state) { 1517 case SynthConstants.ENABLED: return "NORMAL"; 1518 case SynthConstants.PRESSED: return "ACTIVE"; 1519 case SynthConstants.SELECTED: return "SELECTED"; 1520 case SynthConstants.MOUSE_OVER: return "PRELIGHT"; 1521 case SynthConstants.DISABLED: return "INSENSITIVE"; 1522 case UNDEFINED: return undef; 1523 } 1524 1525 return "UNKNOWN"; 1526 } 1527 1528 1534 interface StyleSpecificValue { 1535 public Object getValue(SynthContext context); 1536 } 1537 1538 1539 1542 private static class GTKStockIcon extends SynthIcon implements Cloneable , 1543 StyleSpecificValue { 1544 private String key; 1545 private int size; 1546 private boolean loadedLTR; 1547 private boolean loadedRTL; 1548 private Icon ltrIcon; 1549 private Icon rtlIcon; 1550 private SynthStyle style; 1551 1552 GTKStockIcon(String key, int size) { 1553 this.key = key; 1554 this.size = size; 1555 } 1556 1557 public void paintIcon(SynthContext context, Graphics g, int x, 1558 int y, int w, int h) { 1559 Icon icon = getIcon(context); 1560 1561 if (icon != null) { 1562 if (context == null) { 1563 icon.paintIcon(null, g, x, y); 1564 } 1565 else { 1566 icon.paintIcon(context.getComponent(), g, x, y); 1567 } 1568 } 1569 } 1570 1571 public int getIconWidth(SynthContext context) { 1572 Icon icon = getIcon(context); 1573 1574 if (icon != null) { 1575 return icon.getIconWidth(); 1576 } 1577 return 0; 1578 } 1579 1580 public int getIconHeight(SynthContext context) { 1581 Icon icon = getIcon(context); 1582 1583 if (icon != null) { 1584 return icon.getIconHeight(); 1585 } 1586 return 0; 1587 } 1588 1589 private Icon getIcon(SynthContext context) { 1590 if (context != null) { 1591 ComponentOrientation co = context.getComponent(). 1592 getComponentOrientation(); 1593 SynthStyle style = context.getStyle(); 1594 1595 if (style != this.style) { 1596 this.style = style; 1597 loadedLTR = loadedRTL = false; 1598 } 1599 if (co == null || co.isLeftToRight()) { 1600 if (!loadedLTR) { 1601 loadedLTR = true; 1602 ltrIcon = ((GTKStyle)context.getStyle()). 1603 getStockIcon(context, key, size); 1604 } 1605 return ltrIcon; 1606 } 1607 else if (!loadedRTL) { 1608 loadedRTL = true; 1609 rtlIcon = ((GTKStyle)context.getStyle()). 1610 getStockIcon(context, key,size); 1611 } 1612 return rtlIcon; 1613 } 1614 return ltrIcon; 1615 } 1616 1617 public Object getValue(SynthContext context) { 1618 try { 1619 return clone(); 1620 } catch (CloneNotSupportedException cnse) { 1621 } 1622 return null; 1623 } 1624 } 1625 1626 1627 1632 static class GTKLazyValue implements UIDefaults.LazyValue { 1633 1636 private String className; 1637 private String methodName; 1638 1639 GTKLazyValue(String name) { 1640 this(name, null); 1641 } 1642 1643 GTKLazyValue(String name, String methodName) { 1644 this.className = name; 1645 this.methodName = methodName; 1646 } 1647 1648 public Object createValue(UIDefaults table) { 1649 try { 1650 Class c = Class.forName(className, true,Thread.currentThread(). 1651 getContextClassLoader()); 1652 1653 if (methodName == null) { 1654 return c.newInstance(); 1655 } 1656 Method m = c.getMethod(methodName, null); 1657 1658 return m.invoke(c, null); 1659 } catch (ClassNotFoundException cnfe) { 1660 } catch (IllegalAccessException iae) { 1661 } catch (InvocationTargetException ite) { 1662 } catch (NoSuchMethodException nsme) { 1663 } catch (InstantiationException ie) { 1664 } 1665 return null; 1666 } 1667 } 1668 1669 1670 static { 1671 DEFAULT_COLOR_MAP = new int[] { 1672 SynthConstants.PRESSED, SynthConstants.SELECTED, 1673 SynthConstants.ENABLED, SynthConstants.MOUSE_OVER, 1674 SynthConstants.DISABLED 1675 }; 1676 1677 DEFAULT_COLORS = new Color[5][]; 1678 1679 if (!GTKLookAndFeel.is2_2()) { 1682 DEFAULT_COLORS[0] = getColorsFrom( 1683 new ColorUIResource(195, 195, 195), BLACK_COLOR); 1684 DEFAULT_COLORS[1] = getColorsFrom( 1685 new ColorUIResource(0, 0, 156), WHITE_COLOR); 1686 DEFAULT_COLORS[2] = getColorsFrom( 1687 new ColorUIResource(214, 214, 214), BLACK_COLOR); 1688 DEFAULT_COLORS[3] = getColorsFrom( 1689 new ColorUIResource(233, 233, 233), BLACK_COLOR); 1690 DEFAULT_COLORS[4] = getColorsFrom( 1691 new ColorUIResource(214, 214, 214), 1692 new ColorUIResource(117, 117, 117)); 1693 DEFAULT_COLORS[0][GTKColorType.TEXT_BACKGROUND.getID()] = new 1694 ColorUIResource(188, 210, 238); 1695 DEFAULT_COLORS[1][GTKColorType.TEXT_BACKGROUND.getID()] = new 1696 ColorUIResource(164, 223, 255); 1697 DEFAULT_COLORS[1][GTKColorType.TEXT_FOREGROUND.getID()] = 1698 BLACK_COLOR; 1699 DEFAULT_COLORS[2][GTKColorType.TEXT_FOREGROUND.getID()] = 1700 BLACK_COLOR; 1701 DEFAULT_COLORS[4][GTKColorType.TEXT_FOREGROUND.getID()] = 1702 DEFAULT_COLORS[2][GTKColorType.TEXT_FOREGROUND.getID()]; 1703 } 1704 else { 1705 DEFAULT_COLORS[0] = getColorsFrom( 1707 new ColorUIResource(186, 181, 171), BLACK_COLOR); 1708 DEFAULT_COLORS[1] = getColorsFrom( 1709 new ColorUIResource(75, 105, 131), WHITE_COLOR); 1710 DEFAULT_COLORS[2] = getColorsFrom( 1711 new ColorUIResource(220, 218, 213), BLACK_COLOR); 1712 DEFAULT_COLORS[3] = getColorsFrom( 1713 new ColorUIResource(238, 235, 231), BLACK_COLOR); 1714 DEFAULT_COLORS[4] = getColorsFrom( 1715 new ColorUIResource(220, 218, 213), 1716 new ColorUIResource(117, 117, 117)); 1717 DEFAULT_COLORS[0][GTKColorType.TEXT_BACKGROUND.getID()] = new 1718 ColorUIResource(128, 125, 116); 1719 DEFAULT_COLORS[1][GTKColorType.TEXT_BACKGROUND.getID()] = new 1720 ColorUIResource(75, 105, 131); 1721 DEFAULT_COLORS[2][GTKColorType.TEXT_BACKGROUND.getID()] = 1722 WHITE_COLOR; 1723 DEFAULT_COLORS[3][GTKColorType.TEXT_BACKGROUND.getID()] = 1724 WHITE_COLOR; 1725 DEFAULT_COLORS[4][GTKColorType.TEXT_BACKGROUND.getID()] = new 1726 ColorUIResource(238, 235, 231); 1727 DEFAULT_COLORS[0][GTKColorType.TEXT_FOREGROUND.getID()] = 1728 WHITE_COLOR; 1729 DEFAULT_COLORS[1][GTKColorType.TEXT_FOREGROUND.getID()] = 1730 WHITE_COLOR; 1731 DEFAULT_COLORS[2][GTKColorType.TEXT_FOREGROUND.getID()] = 1732 BLACK_COLOR; 1733 DEFAULT_COLORS[3][GTKColorType.TEXT_FOREGROUND.getID()] = 1734 BLACK_COLOR; 1735 DEFAULT_COLORS[4][GTKColorType.TEXT_FOREGROUND.getID()] = new 1736 ColorUIResource(117, 117, 117); 1737 } 1738 1739 CLASS_SPECIFIC_MAP = new HashMap(); 1740 CLASS_SPECIFIC_MAP.put("CheckBox.iconTextGap", "indicator-spacing"); 1741 CLASS_SPECIFIC_MAP.put("Slider.thumbHeight", "slider-width"); 1742 CLASS_SPECIFIC_MAP.put("Slider.trackBorder", "trough-border"); 1743 CLASS_SPECIFIC_MAP.put("SplitPane.size", "handle-size"); 1744 CLASS_SPECIFIC_MAP.put("Tree.expanderSize", "expander-size"); 1745 CLASS_SPECIFIC_MAP.put("ScrollBar.thumbHeight", "slider-width"); 1746 CLASS_SPECIFIC_MAP.put("TextArea.caretForeground", "cursor-color"); 1747 CLASS_SPECIFIC_MAP.put("TextArea.caretAspectRatio", "cursor-aspect-ratio"); 1748 CLASS_SPECIFIC_MAP.put("TextField.caretForeground", "cursor-color"); 1749 CLASS_SPECIFIC_MAP.put("TextField.caretAspectRatio", "cursor-aspect-ratio"); 1750 CLASS_SPECIFIC_MAP.put("PasswordField.caretForeground", "cursor-color"); 1751 CLASS_SPECIFIC_MAP.put("PasswordField.caretAspectRatio", "cursor-aspect-ratio"); 1752 CLASS_SPECIFIC_MAP.put("FormattedTextField.caretForeground", "cursor-color"); 1753 CLASS_SPECIFIC_MAP.put("FormattedTextField.caretAspectRatio", "cursor-aspect-"); 1754 CLASS_SPECIFIC_MAP.put("TextPane.caretForeground", "cursor-color"); 1755 CLASS_SPECIFIC_MAP.put("TextPane.caretAspectRatio", "cursor-aspect-ratio"); 1756 CLASS_SPECIFIC_MAP.put("EditorPane.caretForeground", "cursor-color"); 1757 CLASS_SPECIFIC_MAP.put("EditorPane.caretAspectRatio", "cursor-aspect-ratio"); 1758 1759 Object [] defaults = { 1760 "FileChooser.cancelIcon", new GTKStockIcon("gtk-cancel", 4), 1761 "FileChooser.okIcon", new GTKStockIcon("gtk-ok", 4), 1762 1763 "OptionPane.errorIcon", new GTKStockIcon("gtk-dialog-error", 6), 1764 "OptionPane.informationIcon", new GTKStockIcon("gtk-dialog-info", 6), 1765 "OptionPane.warningIcon", new GTKStockIcon("gtk-dialog-warning", 6), 1766 "OptionPane.questionIcon", new GTKStockIcon("gtk-dialog-question", 6), 1767 "OptionPane.yesIcon", new GTKStockIcon("gtk-yes", 4), 1768 "OptionPane.noIcon", new GTKStockIcon("gtk-no", 4), 1769 "OptionPane.cancelIcon", new GTKStockIcon("gtk-cancel", 4), 1770 "OptionPane.okIcon", new GTKStockIcon("gtk-ok", 4), 1771 }; 1772 1773 for (int counter = 0, max = defaults.length; counter < max; 1774 counter++) { 1775 DATA.put(defaults[counter], defaults[++counter]); 1776 } 1777 } 1778} 1779 | Popular Tags |