1 7 8 22 23 package com.sun.java.swing.plaf.windows; 24 25 import java.awt.*; 26 import java.awt.image.*; 27 import java.io.*; 28 import java.security.AccessController ; 29 import java.util.*; 30 import java.util.prefs.*; 31 32 import javax.swing.*; 33 import javax.swing.border.*; 34 import javax.swing.plaf.*; 35 import javax.swing.text.JTextComponent ; 36 37 import sun.awt.windows.ThemeReader; 38 import sun.security.action.GetPropertyAction; 39 import sun.swing.CachedPainter; 40 41 import com.sun.java.swing.plaf.windows.TMSchema.*; 42 43 49 class XPStyle { 50 private static XPStyle xp; 52 53 private static SkinPainter skinPainter = new SkinPainter(); 55 56 private static Boolean themeActive = null; 57 58 private HashMap<String , Border> borderMap; 59 private HashMap<String , Color> colorMap; 60 61 private boolean flatMenus; 62 63 static { 64 invalidateStyle(); 65 } 66 67 70 static synchronized void invalidateStyle() { 71 xp = null; 72 themeActive = null; 73 } 74 75 80 static synchronized XPStyle getXP() { 81 if (themeActive == null) { 82 Toolkit toolkit = Toolkit.getDefaultToolkit(); 83 themeActive = 84 (Boolean )toolkit.getDesktopProperty("win.xpstyle.themeActive"); 85 if (themeActive == null) { 86 themeActive = Boolean.FALSE; 87 } 88 if (themeActive.booleanValue()) { 89 GetPropertyAction propertyAction = 90 new GetPropertyAction("swing.noxp"); 91 if (AccessController.doPrivileged(propertyAction) == null && 92 ThemeReader.isThemed() && 93 !(UIManager.getLookAndFeel() 94 instanceof WindowsClassicLookAndFeel)) { 95 96 xp = new XPStyle(); 97 } 98 } 99 } 100 return xp; 101 } 102 103 104 105 116 String getString(Component c, Part part, State state, Prop prop) { 117 return getTypeEnumName(c, part, state, prop); 118 } 119 120 private static String getTypeEnumName(Component c, Part part, State state, Prop prop) { 121 int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(), 122 State.getValue(part, state), 123 prop.getValue()); 124 if (enumValue == -1) { 125 return null; 126 } 127 return TypeEnum.getTypeEnum(prop, enumValue).getName(); 128 } 129 130 131 132 133 139 int getInt(Component c, Part part, State state, Prop prop, int fallback) { 140 return ThemeReader.getInt(part.getControlName(c), part.getValue(), 141 State.getValue(part, state), 142 prop.getValue()); 143 } 144 145 154 Dimension getDimension(Component c, Part part, State state, Prop prop) { 155 return ThemeReader.getPosition(part.getControlName(c), part.getValue(), 156 State.getValue(part, state), 157 prop.getValue()); 158 } 159 160 170 Point getPoint(Component c, Part part, State state, Prop prop) { 171 Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(), 172 State.getValue(part, state), 173 prop.getValue()); 174 if (d != null) { 175 return new Point(d.width, d.height); 176 } else { 177 return null; 178 } 179 } 180 181 191 Insets getMargin(Component c, Part part, State state, Prop prop) { 192 return ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(), 193 State.getValue(part, state), 194 prop.getValue()); 195 } 196 197 198 204 synchronized Color getColor(Skin skin, Prop prop, Color fallback) { 205 String key = skin.toString() + "." + prop.name(); 206 Part part = skin.part; 207 Color color = colorMap.get(key); 208 if (color == null) { 209 color = ThemeReader.getColor(part.getControlName(null), part.getValue(), 210 State.getValue(part, skin.state), 211 prop.getValue()); 212 if (color != null) { 213 color = new ColorUIResource(color); 214 colorMap.put(key, color); 215 } 216 } 217 return (color != null) ? color : fallback; 218 } 219 220 Color getColor(Component c, Part part, State state, Prop prop, Color fallback) { 221 return getColor(new Skin(c, part, state), prop, fallback); 222 } 223 224 225 226 233 synchronized Border getBorder(Component c, Part part) { 234 if (part == Part.MENU) { 235 if (flatMenus) { 237 return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"), 241 1); 242 } else { 243 return null; } 245 } 246 Skin skin = new Skin(c, part, null); 247 Border border = borderMap.get(skin.string); 248 if (border == null) { 249 String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE); 250 if ("borderfill".equalsIgnoreCase(bgType)) { 251 int thickness = getInt(c, part, null, Prop.BORDERSIZE, 1); 252 Color color = getColor(skin, Prop.BORDERCOLOR, Color.black); 253 border = new XPFillBorder(color, thickness); 254 } else if ("imagefile".equalsIgnoreCase(bgType)) { 255 Insets m = getMargin(c, part, null, Prop.SIZINGMARGINS); 256 if (m != null) { 257 if (getBoolean(c, part, null, Prop.BORDERONLY)) { 258 border = new XPImageBorder(c, part); 259 } else { 260 if(part == Part.TP_BUTTON) { 261 border = new XPEmptyBorder(new Insets(3,3,3,3)); 262 } else { 263 border = new XPEmptyBorder(m); 264 } 265 } 266 } 267 } 268 if (border != null) { 269 borderMap.put(skin.string, border); 270 } 271 } 272 return border; 273 } 274 275 private class XPFillBorder extends LineBorder implements UIResource { 276 XPFillBorder(Color color, int thickness) { 277 super(color, thickness); 278 } 279 280 public Insets getBorderInsets(Component c) { 281 return getBorderInsets(c, new Insets(0,0,0,0)); 282 } 283 284 public Insets getBorderInsets(Component c, Insets insets) { 285 Insets margin = null; 286 if (c instanceof AbstractButton) { 292 margin = ((AbstractButton)c).getMargin(); 293 } else if (c instanceof JToolBar) { 294 margin = ((JToolBar)c).getMargin(); 295 } else if (c instanceof JTextComponent ) { 296 margin = ((JTextComponent )c).getMargin(); 297 } 298 insets.top = (margin != null? margin.top : 0) + thickness; 299 insets.left = (margin != null? margin.left : 0) + thickness; 300 insets.bottom = (margin != null? margin.bottom : 0) + thickness; 301 insets.right = (margin != null? margin.right : 0) + thickness; 302 303 return insets; 304 } 305 } 306 307 private class XPImageBorder extends AbstractBorder implements UIResource { 308 Skin skin; 309 310 XPImageBorder(Component c, Part part) { 311 this.skin = getSkin(c, part); 312 } 313 314 public void paintBorder(Component c, Graphics g, 315 int x, int y, int width, int height) { 316 skin.paintSkin(g, x, y, width, height, null); 317 } 318 319 public Insets getBorderInsets(Component c) { 320 return getBorderInsets(c, new Insets(0,0,0,0)); 321 } 322 323 public Insets getBorderInsets(Component c, Insets insets) { 324 Insets margin = null; 325 Insets borderInsets = skin.getContentMargin(); 326 if (c instanceof AbstractButton) { 332 margin = ((AbstractButton)c).getMargin(); 333 } else if (c instanceof JToolBar) { 334 margin = ((JToolBar)c).getMargin(); 335 } else if (c instanceof JTextComponent ) { 336 margin = ((JTextComponent )c).getMargin(); 337 } 338 insets.top = (margin != null? margin.top : 0) + borderInsets.top; 339 insets.left = (margin != null? margin.left : 0) + borderInsets.left; 340 insets.bottom = (margin != null? margin.bottom : 0) + borderInsets.bottom; 341 insets.right = (margin != null? margin.right : 0) + borderInsets.right; 342 343 return insets; 344 } 345 } 346 347 private class XPEmptyBorder extends EmptyBorder implements UIResource { 348 XPEmptyBorder(Insets m) { 349 super(m.top+2, m.left+2, m.bottom+2, m.right+2); 350 } 351 352 public Insets getBorderInsets(Component c) { 353 return getBorderInsets(c, getBorderInsets()); 354 } 355 356 public Insets getBorderInsets(Component c, Insets insets) { 357 insets = super.getBorderInsets(c, insets); 358 359 Insets margin = null; 360 if (c instanceof AbstractButton) { 361 Insets m = ((AbstractButton)c).getMargin(); 362 if(c.getParent() instanceof JToolBar 365 && ! (c instanceof JRadioButton) 366 && ! (c instanceof JCheckBox) 367 && m instanceof InsetsUIResource) { 368 insets.top -= 2; 369 insets.left -= 2; 370 insets.bottom -= 2; 371 insets.right -= 2; 372 } else { 373 margin = m; 374 } 375 } else if (c instanceof JToolBar) { 376 margin = ((JToolBar)c).getMargin(); 377 } else if (c instanceof JTextComponent ) { 378 margin = ((JTextComponent )c).getMargin(); 379 } 380 if (margin != null) { 381 insets.top = margin.top + 2; 382 insets.left = margin.left + 2; 383 insets.bottom = margin.bottom + 2; 384 insets.right = margin.right + 2; 385 } 386 return insets; 387 } 388 } 389 390 boolean isSkinDefined(Component c, Part part) { 391 return (part.getValue() == 0) 392 || ThemeReader.isThemePartDefined( 393 part.getControlName(c), part.getValue(), 0); 394 } 395 396 402 synchronized Skin getSkin(Component c, Part part) { 403 assert isSkinDefined(c, part) : "part " + part + " is not defined"; 404 return new Skin(c, part, null); 405 } 406 407 408 409 410 414 static class Skin { 415 final Component component; 416 final Part part; 417 final State state; 418 419 private final String string; 420 private Dimension size = null; 421 422 Skin(Component component, Part part) { 423 this(component, part, null); 424 } 425 426 Skin(Part part, State state) { 427 this(null, part, state); 428 } 429 430 Skin(Component component, Part part, State state) { 431 this.component = component; 432 this.part = part; 433 this.state = state; 434 435 String str = part.getControlName(component) +"." + part.name(); 436 if (state != null) { 437 str += "("+state.name()+")"; 438 } 439 string = str; 440 } 441 442 Insets getContentMargin() { 443 return ThemeReader.getThemeMargins(part.getControlName(null), part.getValue(), 445 0, Prop.SIZINGMARGINS.getValue()); 446 } 447 448 private int getWidth(State state) { 449 if (size == null) { 450 size = getPartSize(part, state); 451 } 452 return size.width; 453 } 454 455 int getWidth() { 456 return getWidth((state != null) ? state : State.NORMAL); 457 } 458 459 private int getHeight(State state) { 460 if (size == null) { 461 size = getPartSize(part, state); 462 } 463 return size.height; 464 } 465 466 int getHeight() { 467 return getHeight((state != null) ? state : State.NORMAL); 468 } 469 470 public String toString() { 471 return string; 472 } 473 474 public boolean equals(Object obj) { 475 return (obj instanceof Skin && ((Skin)obj).string.equals(string)); 476 } 477 478 public int hashCode() { 479 return string.hashCode(); 480 } 481 482 489 void paintSkin(Graphics g, int dx, int dy, State state) { 490 if (state == null) { 491 state = this.state; 492 } 493 paintSkin(g, dx, dy, getWidth(state), getHeight(state), state); 494 } 495 496 503 void paintSkin(Graphics g, Rectangle r, State state) { 504 paintSkin(g, r.x, r.y, r.width, r.height, state); 505 } 506 507 518 void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) { 519 skinPainter.paint(null, g, dx, dy, dw, dh, this, state); 520 } 521 535 void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state, 536 boolean borderFill) { 537 if(borderFill && "borderfill".equals(getTypeEnumName(component, part, 538 state, Prop.BGTYPE))) { 539 return; 540 } 541 skinPainter.paint(null, g, dx, dy, dw, dh, this, state); 542 } 543 } 544 545 private static class SkinPainter extends CachedPainter { 546 SkinPainter() { 547 super(30); 548 flush(); 549 } 550 551 protected void paintToImage(Component c, Image image, Graphics g, 552 int w, int h, Object [] args) { 553 Skin skin = (Skin)args[0]; 554 Part part = skin.part; 555 State state = (State)args[1]; 556 if (state == null) { 557 state = skin.state; 558 } 559 if (c == null) { 560 c = skin.component; 561 } 562 WritableRaster raster = ((BufferedImage)image).getRaster(); 563 DataBufferInt buffer = (DataBufferInt)raster.getDataBuffer(); 564 ThemeReader.paintBackground(buffer.getData(), 565 part.getControlName(c), part.getValue(), 566 State.getValue(part, state), 567 0, 0, w, h, w); 568 } 569 570 protected Image createImage(Component c, int w, int h, 571 GraphicsConfiguration config, Object [] args) { 572 return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 573 } 574 } 575 576 static class GlyphButton extends JButton { 577 private Skin skin; 578 579 public GlyphButton(Component parent, Part part) { 580 XPStyle xp = getXP(); 581 skin = xp.getSkin(parent, part); 582 setBorder(null); 583 setContentAreaFilled(false); 584 } 585 586 public boolean isFocusTraversable() { 587 return false; 588 } 589 590 protected State getState() { 591 State state = State.NORMAL; 592 if (!isEnabled()) { 593 state = State.DISABLED; 594 } else if (getModel().isPressed()) { 595 state = State.PRESSED; 596 } else if (getModel().isRollover()) { 597 state = State.HOT; 598 } 599 return state; 600 } 601 602 public void paintComponent(Graphics g) { 603 Dimension d = getSize(); 604 skin.paintSkin(g, 0, 0, d.width, d.height, getState()); 605 } 606 607 public void setPart(Component parent, Part part) { 608 XPStyle xp = getXP(); 609 skin = xp.getSkin(parent, part); 610 revalidate(); 611 repaint(); 612 } 613 614 protected void paintBorder(Graphics g) { 615 } 616 617 public Dimension getPreferredSize() { 618 return new Dimension(16, 16); 619 } 620 621 public Dimension getMinimumSize() { 622 return new Dimension(5, 5); 623 } 624 625 public Dimension getMaximumSize() { 626 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 627 } 628 } 629 630 private XPStyle() { 632 flatMenus = getSysBoolean(Prop.FLATMENUS); 633 634 colorMap = new HashMap<String , Color>(); 635 borderMap = new HashMap<String , Border>(); 636 } 638 639 640 private boolean getBoolean(Component c, Part part, State state, Prop prop) { 641 return ThemeReader.getBoolean(part.getControlName(c), part.getValue(), 642 State.getValue(part, state), 643 prop.getValue()); 644 } 645 646 private static Dimension getPartSize(Part part, State state) { 647 return ThemeReader.getPartSize(part.getControlName(null), part.getValue(), 648 State.getValue(part, state)); 649 } 650 651 private static boolean getSysBoolean(Prop prop) { 652 return ThemeReader.getSysBoolean("window", prop.getValue()); 654 } 655 } 656 | Popular Tags |