Advertisement
Guest User

Untitled

a guest
May 1st, 2018
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.29 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25.  
  26. /*
  27. * <p>These classes are designed to be used while the
  28. * corresponding <code>LookAndFeel</code> class has been installed
  29. * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>).
  30. * Using them while a different <code>LookAndFeel</code> is installed
  31. * may produce unexpected results, including exceptions.
  32. * Additionally, changing the <code>LookAndFeel</code>
  33. * maintained by the <code>UIManager</code> without updating the
  34. * corresponding <code>ComponentUI</code> of any
  35. * <code>JComponent</code>s may also produce unexpected results,
  36. * such as the wrong colors showing up, and is generally not
  37. * encouraged.
  38. *
  39. */
  40.  
  41. package com.sun.java.swing.plaf.windows;
  42.  
  43. import java.awt.*;
  44. import java.awt.image.*;
  45. import java.security.AccessController;
  46. import java.util.*;
  47.  
  48. import javax.swing.*;
  49. import javax.swing.border.*;
  50. import javax.swing.plaf.*;
  51. import javax.swing.text.JTextComponent;
  52.  
  53. import sun.awt.image.SunWritableRaster;
  54. import sun.awt.windows.ThemeReader;
  55. import sun.security.action.GetPropertyAction;
  56. import sun.swing.CachedPainter;
  57.  
  58. import static com.sun.java.swing.plaf.windows.TMSchema.*;
  59.  
  60.  
  61. /**
  62. * Implements Windows XP Styles for the Windows Look and Feel.
  63. *
  64. * @author Leif Samuelsson
  65. */
  66. class XPStyle2 {
  67. // Singleton instance of this class
  68. private static XPStyle2 xp;
  69.  
  70. // Singleton instance of SkinPainter
  71. private static SkinPainter skinPainter = new SkinPainter();
  72.  
  73. private static Boolean themeActive = null;
  74.  
  75. private HashMap<String, Border> borderMap;
  76. private HashMap<String, Color> colorMap;
  77.  
  78. private boolean flatMenus;
  79.  
  80. static {
  81. invalidateStyle();
  82. }
  83.  
  84. /** Static method for clearing the hashmap and loading the
  85. * current XP style and theme
  86. */
  87. static synchronized void invalidateStyle() {
  88. xp = null;
  89. themeActive = null;
  90. skinPainter.flush();
  91. }
  92.  
  93. /** Get the singleton instance of this class
  94. *
  95. * @return the singleton instance of this class or null if XP styles
  96. * are not active or if this is not Windows XP
  97. */
  98. static synchronized XPStyle2 getXP() {
  99. if (themeActive == null) {
  100. Toolkit toolkit = Toolkit.getDefaultToolkit();
  101. themeActive =
  102. (Boolean)toolkit.getDesktopProperty("win.xpstyle.themeActive");
  103. if (themeActive == null) {
  104. themeActive = Boolean.FALSE;
  105. }
  106. if (themeActive.booleanValue()) {
  107. GetPropertyAction propertyAction =
  108. new GetPropertyAction("swing.noxp");
  109. if (AccessController.doPrivileged(propertyAction) == null &&
  110. ThemeReader.isThemed() &&
  111. !(UIManager.getLookAndFeel()
  112. instanceof WindowsClassicLookAndFeel)) {
  113.  
  114. xp = new XPStyle2();
  115. }
  116. }
  117. }
  118. return ThemeReader.isXPStyleEnabled() ? xp : null;
  119. }
  120.  
  121. static boolean isVista() {
  122. XPStyle2 xp = XPStyle2.getXP();
  123. return (xp != null && xp.isSkinDefined(null, Part.CP_DROPDOWNBUTTONRIGHT));
  124. }
  125.  
  126. /** Get a named <code>String</code> value from the current style
  127. *
  128. * @param part a <code>Part</code>
  129. * @param state a <code>String</code>
  130. * @param attributeKey a <code>String</code>
  131. * @return a <code>String</code> or null if key is not found
  132. * in the current style
  133. *
  134. * This is currently only used by WindowsInternalFrameTitlePane for painting
  135. * title foregound and can be removed when no longer needed
  136. */
  137. String getString(Component c, Part part, State state, Prop prop) {
  138. return getTypeEnumName(c, part, state, prop);
  139. }
  140.  
  141. TypeEnum getTypeEnum(Component c, Part part, State state, Prop prop) {
  142. int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
  143. State.getValue(part, state),
  144. prop.getValue());
  145. return TypeEnum.getTypeEnum(prop, enumValue);
  146. }
  147.  
  148. private static String getTypeEnumName(Component c, Part part, State state, Prop prop) {
  149. int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
  150. State.getValue(part, state),
  151. prop.getValue());
  152. if (enumValue == -1) {
  153. return null;
  154. }
  155. return TypeEnum.getTypeEnum(prop, enumValue).getName();
  156. }
  157.  
  158.  
  159.  
  160.  
  161. /** Get a named <code>int</code> value from the current style
  162. *
  163. * @param part a <code>Part</code>
  164. * @return an <code>int</code> or null if key is not found
  165. * in the current style
  166. */
  167. int getInt(Component c, Part part, State state, Prop prop, int fallback) {
  168. return ThemeReader.getInt(part.getControlName(c), part.getValue(),
  169. State.getValue(part, state),
  170. prop.getValue());
  171. }
  172.  
  173. /** Get a named <code>Dimension</code> value from the current style
  174. *
  175. * @param key a <code>String</code>
  176. * @return a <code>Dimension</code> or null if key is not found
  177. * in the current style
  178. *
  179. * This is currently only used by WindowsProgressBarUI and the value
  180. * should probably be cached there instead of here.
  181. */
  182. Dimension getDimension(Component c, Part part, State state, Prop prop) {
  183. Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
  184. State.getValue(part, state),
  185. prop.getValue());
  186. return (d != null) ? d : new Dimension();
  187. }
  188.  
  189. /** Get a named <code>Point</code> (e.g. a location or an offset) value
  190. * from the current style
  191. *
  192. * @param key a <code>String</code>
  193. * @return a <code>Point</code> or null if key is not found
  194. * in the current style
  195. *
  196. * This is currently only used by WindowsInternalFrameTitlePane for painting
  197. * title foregound and can be removed when no longer needed
  198. */
  199. Point getPoint(Component c, Part part, State state, Prop prop) {
  200. Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
  201. State.getValue(part, state),
  202. prop.getValue());
  203. return (d != null) ? new Point(d.width, d.height) : new Point();
  204. }
  205.  
  206. /** Get a named <code>Insets</code> value from the current style
  207. *
  208. * @param key a <code>String</code>
  209. * @return an <code>Insets</code> object or null if key is not found
  210. * in the current style
  211. *
  212. * This is currently only used to create borders and by
  213. * WindowsInternalFrameTitlePane for painting title foregound.
  214. * The return value is already cached in those places.
  215. */
  216. Insets getMargin(Component c, Part part, State state, Prop prop) {
  217. Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),
  218. State.getValue(part, state),
  219. prop.getValue());
  220. return (insets != null) ? insets : new Insets(0, 0, 0, 0);
  221. }
  222.  
  223.  
  224. /** Get a named <code>Color</code> value from the current style
  225. *
  226. * @param part a <code>Part</code>
  227. * @return a <code>Color</code> or null if key is not found
  228. * in the current style
  229. */
  230. synchronized Color getColor(Skin skin, Prop prop, Color fallback) {
  231. String key = skin.toString() + "." + prop.name();
  232. Part part = skin.part;
  233. Color color = colorMap.get(key);
  234. if (color == null) {
  235. color = ThemeReader.getColor(part.getControlName(null), part.getValue(),
  236. State.getValue(part, skin.state),
  237. prop.getValue());
  238. if (color != null) {
  239. color = new ColorUIResource(color);
  240. colorMap.put(key, color);
  241. }
  242. }
  243. return (color != null) ? color : fallback;
  244. }
  245.  
  246. Color getColor(Component c, Part part, State state, Prop prop, Color fallback) {
  247. return getColor(new Skin(c, part, state), prop, fallback);
  248. }
  249.  
  250.  
  251.  
  252. /** Get a named <code>Border</code> value from the current style
  253. *
  254. * @param part a <code>Part</code>
  255. * @return a <code>Border</code> or null if key is not found
  256. * in the current style or if the style for the particular
  257. * part is not defined as "borderfill".
  258. */
  259. synchronized Border getBorder(Component c, Part part) {
  260. if (part == Part.MENU) {
  261. // Special case because XP has no skin for menus
  262. if (flatMenus) {
  263. // TODO: The classic border uses this color, but we should
  264. // create a new UI property called "PopupMenu.borderColor"
  265. // instead.
  266. return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"),
  267. 1);
  268. } else {
  269. return null; // Will cause L&F to use classic border
  270. }
  271. }
  272. Skin skin = new Skin(c, part, null);
  273. Border border = borderMap.get(skin.string);
  274. if (border == null) {
  275. String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE);
  276. if ("borderfill".equalsIgnoreCase(bgType)) {
  277. int thickness = getInt(c, part, null, Prop.BORDERSIZE, 1);
  278. Color color = getColor(skin, Prop.BORDERCOLOR, Color.black);
  279. border = new XPFillBorder(color, thickness);
  280. if (part == Part.CP_COMBOBOX) {
  281. border = new XPStatefulFillBorder(color, thickness, part, Prop.BORDERCOLOR);
  282. }
  283. } else if ("imagefile".equalsIgnoreCase(bgType)) {
  284. Insets m = getMargin(c, part, null, Prop.SIZINGMARGINS);
  285. if (m != null) {
  286. if (getBoolean(c, part, null, Prop.BORDERONLY)) {
  287. border = new XPImageBorder(c, part);
  288. } else if (part == Part.CP_COMBOBOX) {
  289. border = new EmptyBorder(1, 1, 1, 1);
  290. } else {
  291. if(part == Part.TP_BUTTON) {
  292. border = new XPEmptyBorder(new Insets(3,3,3,3));
  293. } else {
  294. border = new XPEmptyBorder(m);
  295. }
  296. }
  297. }
  298. }
  299. if (border != null) {
  300. borderMap.put(skin.string, border);
  301. }
  302. }
  303. return border;
  304. }
  305.  
  306. private class XPFillBorder extends LineBorder implements UIResource {
  307. XPFillBorder(Color color, int thickness) {
  308. super(color, thickness);
  309. }
  310.  
  311. public Insets getBorderInsets(Component c, Insets insets) {
  312. Insets margin = null;
  313. //
  314. // Ideally we'd have an interface defined for classes which
  315. // support margins (to avoid this hackery), but we've
  316. // decided against it for simplicity
  317. //
  318. if (c instanceof AbstractButton) {
  319. margin = ((AbstractButton)c).getMargin();
  320. } else if (c instanceof JToolBar) {
  321. margin = ((JToolBar)c).getMargin();
  322. } else if (c instanceof JTextComponent) {
  323. margin = ((JTextComponent)c).getMargin();
  324. }
  325. insets.top = (margin != null? margin.top : 0) + thickness;
  326. insets.left = (margin != null? margin.left : 0) + thickness;
  327. insets.bottom = (margin != null? margin.bottom : 0) + thickness;
  328. insets.right = (margin != null? margin.right : 0) + thickness;
  329.  
  330. return insets;
  331. }
  332. }
  333.  
  334. private class XPStatefulFillBorder extends XPFillBorder {
  335. private final Part part;
  336. private final Prop prop;
  337. XPStatefulFillBorder(Color color, int thickness, Part part, Prop prop) {
  338. super(color, thickness);
  339. this.part = part;
  340. this.prop = prop;
  341. }
  342.  
  343. public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  344. State state = State.NORMAL;
  345. // special casing for comboboxes.
  346. // there may be more special cases in the future
  347. if(c instanceof JComboBox) {
  348. JComboBox cb = (JComboBox)c;
  349. // note. in the future this should be replaced with a call
  350. // to BasicLookAndFeel.getUIOfType()
  351. if(cb.getUI() instanceof WindowsComboBoxUI) {
  352. WindowsComboBoxUI wcb = (WindowsComboBoxUI)cb.getUI();
  353. state = wcb.getXPComboBoxState(cb);
  354. }
  355. }
  356. lineColor = getColor(c, part, state, prop, Color.black);
  357. super.paintBorder(c, g, x, y, width, height);
  358. }
  359. }
  360.  
  361. private class XPImageBorder extends AbstractBorder implements UIResource {
  362. Skin skin;
  363.  
  364. XPImageBorder(Component c, Part part) {
  365. this.skin = getSkin(c, part);
  366. }
  367.  
  368. public void paintBorder(Component c, Graphics g,
  369. int x, int y, int width, int height) {
  370. skin.paintSkin(g, x, y, width, height, null);
  371. }
  372.  
  373. public Insets getBorderInsets(Component c, Insets insets) {
  374. Insets margin = null;
  375. Insets borderInsets = skin.getContentMargin();
  376. if(borderInsets == null) {
  377. borderInsets = new Insets(0, 0, 0, 0);
  378. }
  379. //
  380. // Ideally we'd have an interface defined for classes which
  381. // support margins (to avoid this hackery), but we've
  382. // decided against it for simplicity
  383. //
  384. if (c instanceof AbstractButton) {
  385. margin = ((AbstractButton)c).getMargin();
  386. } else if (c instanceof JToolBar) {
  387. margin = ((JToolBar)c).getMargin();
  388. } else if (c instanceof JTextComponent) {
  389. margin = ((JTextComponent)c).getMargin();
  390. }
  391. insets.top = (margin != null? margin.top : 0) + borderInsets.top;
  392. insets.left = (margin != null? margin.left : 0) + borderInsets.left;
  393. insets.bottom = (margin != null? margin.bottom : 0) + borderInsets.bottom;
  394. insets.right = (margin != null? margin.right : 0) + borderInsets.right;
  395.  
  396. return insets;
  397. }
  398. }
  399.  
  400. private class XPEmptyBorder extends EmptyBorder implements UIResource {
  401. XPEmptyBorder(Insets m) {
  402. super(m.top+2, m.left+2, m.bottom+2, m.right+2);
  403. }
  404.  
  405. public Insets getBorderInsets(Component c, Insets insets) {
  406. insets = super.getBorderInsets(c, insets);
  407.  
  408. Insets margin = null;
  409. if (c instanceof AbstractButton) {
  410. Insets m = ((AbstractButton)c).getMargin();
  411. // if this is a toolbar button then ignore getMargin()
  412. // and subtract the padding added by the constructor
  413. if(c.getParent() instanceof JToolBar
  414. && ! (c instanceof JRadioButton)
  415. && ! (c instanceof JCheckBox)
  416. && m instanceof InsetsUIResource) {
  417. insets.top -= 2;
  418. insets.left -= 2;
  419. insets.bottom -= 2;
  420. insets.right -= 2;
  421. } else {
  422. margin = m;
  423. }
  424. } else if (c instanceof JToolBar) {
  425. margin = ((JToolBar)c).getMargin();
  426. } else if (c instanceof JTextComponent) {
  427. margin = ((JTextComponent)c).getMargin();
  428. }
  429. if (margin != null) {
  430. insets.top = margin.top + 2;
  431. insets.left = margin.left + 2;
  432. insets.bottom = margin.bottom + 2;
  433. insets.right = margin.right + 2;
  434. }
  435. return insets;
  436. }
  437. }
  438. boolean isSkinDefined(Component c, Part part) {
  439. return (part.getValue() == 0)
  440. || ThemeReader.isThemePartDefined(
  441. part.getControlName(c), part.getValue(), 0);
  442. }
  443.  
  444.  
  445. /** Get a <code>Skin</code> object from the current style
  446. * for a named part (component type)
  447. *
  448. * @param part a <code>Part</code>
  449. * @return a <code>Skin</code> object
  450. */
  451. synchronized Skin getSkin(Component c, Part part) {
  452. assert isSkinDefined(c, part) : "part " + part + " is not defined";
  453. return new Skin(c, part, null);
  454. }
  455.  
  456.  
  457. long getThemeTransitionDuration(Component c, Part part, State stateFrom,
  458. State stateTo, Prop prop) {
  459. return ThemeReader.getThemeTransitionDuration(part.getControlName(c),
  460. part.getValue(),
  461. State.getValue(part, stateFrom),
  462. State.getValue(part, stateTo),
  463. (prop != null) ? prop.getValue() : 0);
  464. }
  465.  
  466.  
  467. /** A class which encapsulates attributes for a given part
  468. * (component type) and which provides methods for painting backgrounds
  469. * and glyphs
  470. */
  471. static class Skin {
  472. final Component component;
  473. final Part part;
  474. final State state;
  475.  
  476. private final String string;
  477. private Dimension size = null;
  478.  
  479. Skin(Component component, Part part) {
  480. this(component, part, null);
  481. }
  482.  
  483. Skin(Part part, State state) {
  484. this(null, part, state);
  485. }
  486.  
  487. Skin(Component component, Part part, State state) {
  488. this.component = component;
  489. this.part = part;
  490. this.state = state;
  491.  
  492. String str = part.getControlName(component) +"." + part.name();
  493. if (state != null) {
  494. str += "("+state.name()+")";
  495. }
  496. string = str;
  497. }
  498.  
  499. Insets getContentMargin() {
  500. /* idk: it seems margins are the same for all 'big enough'
  501. * bounding rectangles.
  502. */
  503. int boundingWidth = 100;
  504. int boundingHeight = 100;
  505.  
  506. Insets insets = ThemeReader.getThemeBackgroundContentMargins(
  507. part.getControlName(null), part.getValue(),
  508. 0, boundingWidth, boundingHeight);
  509. return (insets != null) ? insets : new Insets(0, 0, 0, 0);
  510. }
  511.  
  512. private int getWidth(State state) {
  513. if (size == null) {
  514. size = getPartSize(part, state);
  515. }
  516. return (size != null) ? size.width : 0;
  517. }
  518.  
  519. int getWidth() {
  520. return getWidth((state != null) ? state : State.NORMAL);
  521. }
  522.  
  523. private int getHeight(State state) {
  524. if (size == null) {
  525. size = getPartSize(part, state);
  526. }
  527. return (size != null) ? size.height : 0;
  528. }
  529.  
  530. int getHeight() {
  531. return getHeight((state != null) ? state : State.NORMAL);
  532. }
  533.  
  534. public String toString() {
  535. return string;
  536. }
  537.  
  538. public boolean equals(Object obj) {
  539. return (obj instanceof Skin && ((Skin)obj).string.equals(string));
  540. }
  541.  
  542. public int hashCode() {
  543. return string.hashCode();
  544. }
  545.  
  546. /** Paint a skin at x, y.
  547. *
  548. * @param g the graphics context to use for painting
  549. * @param dx the destination <i>x</i> coordinate
  550. * @param dy the destination <i>y</i> coordinate
  551. * @param state which state to paint
  552. */
  553. void paintSkin(Graphics g, int dx, int dy, State state) {
  554. if (state == null) {
  555. state = this.state;
  556. }
  557. paintSkin(g, dx, dy, getWidth(state), getHeight(state), state);
  558. }
  559.  
  560. /** Paint a skin in an area defined by a rectangle.
  561. *
  562. * @param g the graphics context to use for painting
  563. * @param r a <code>Rectangle</code> defining the area to fill,
  564. * may cause the image to be stretched or tiled
  565. * @param state which state to paint
  566. */
  567. void paintSkin(Graphics g, Rectangle r, State state) {
  568. paintSkin(g, r.x, r.y, r.width, r.height, state);
  569. }
  570.  
  571. /** Paint a skin at a defined position and size
  572. * This method supports animation.
  573. *
  574. * @param g the graphics context to use for painting
  575. * @param dx the destination <i>x</i> coordinate
  576. * @param dy the destination <i>y</i> coordinate
  577. * @param dw the width of the area to fill, may cause
  578. * the image to be stretched or tiled
  579. * @param dh the height of the area to fill, may cause
  580. * the image to be stretched or tiled
  581. * @param state which state to paint
  582. */
  583. void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) {
  584. if (XPStyle2.getXP() == null) {
  585. return;
  586. }
  587. if (ThemeReader.isGetThemeTransitionDurationDefined()
  588. && component instanceof JComponent
  589. && SwingUtilities.getAncestorOfClass(CellRendererPane.class,
  590. component) == null) {
  591. AnimationController2.paintSkin((JComponent) component, this,
  592. g, dx, dy, dw, dh, state);
  593. } else {
  594. paintSkinRaw(g, dx, dy, dw, dh, state);
  595. }
  596. }
  597.  
  598. /** Paint a skin at a defined position and size. This method
  599. * does not trigger animation. It is needed for the animation
  600. * support.
  601. *
  602. * @param g the graphics context to use for painting
  603. * @param dx the destination <i>x</i> coordinate.
  604. * @param dy the destination <i>y</i> coordinate.
  605. * @param dw the width of the area to fill, may cause
  606. * the image to be stretched or tiled
  607. * @param dh the height of the area to fill, may cause
  608. * the image to be stretched or tiled
  609. * @param state which state to paint
  610. */
  611. void paintSkinRaw(Graphics g, int dx, int dy, int dw, int dh, State state) {
  612. if (XPStyle2.getXP() == null) {
  613. return;
  614. }
  615. skinPainter.paint(null, g, dx, dy, dw, dh, this, state);
  616. }
  617.  
  618. /** Paint a skin at a defined position and size
  619. *
  620. * @param g the graphics context to use for painting
  621. * @param dx the destination <i>x</i> coordinate
  622. * @param dy the destination <i>y</i> coordinate
  623. * @param dw the width of the area to fill, may cause
  624. * the image to be stretched or tiled
  625. * @param dh the height of the area to fill, may cause
  626. * the image to be stretched or tiled
  627. * @param state which state to paint
  628. * @param borderFill should test if the component uses a border fill
  629. and skip painting if it is
  630. */
  631. void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state,
  632. boolean borderFill) {
  633. if (XPStyle2.getXP() == null) {
  634. return;
  635. }
  636. if(borderFill && "borderfill".equals(getTypeEnumName(component, part,
  637. state, Prop.BGTYPE))) {
  638. return;
  639. }
  640. skinPainter.paint(null, g, dx, dy, dw, dh, this, state);
  641. }
  642. }
  643.  
  644. private static class SkinPainter extends CachedPainter {
  645. SkinPainter() {
  646. super(30);
  647. flush();
  648. }
  649.  
  650. public void flush() {
  651. super.flush();
  652. }
  653.  
  654. protected void paintToImage(Component c, Image image, Graphics g,
  655. int w, int h, Object[] args) {
  656. boolean accEnabled = false;
  657. Skin skin = (Skin)args[0];
  658. Part part = skin.part;
  659. State state = (State)args[1];
  660. if (state == null) {
  661. state = skin.state;
  662. }
  663. if (c == null) {
  664. c = skin.component;
  665. }
  666. BufferedImage bi = (BufferedImage)image;
  667.  
  668. WritableRaster raster = bi.getRaster();
  669. DataBufferInt dbi = (DataBufferInt)raster.getDataBuffer();
  670. // Note that stealData() requires a markDirty() afterwards
  671. // since we modify the data in it.
  672. ThemeReader.paintBackground(SunWritableRaster.stealData(dbi, 0),
  673. part.getControlName(c), part.getValue(),
  674. State.getValue(part, state),
  675. 0, 0, w, h, w);
  676. SunWritableRaster.markDirty(dbi);
  677. }
  678.  
  679. protected Image createImage(Component c, int w, int h,
  680. GraphicsConfiguration config, Object[] args) {
  681. return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
  682. }
  683. }
  684.  
  685. static class GlyphButton extends JButton {
  686. private Skin skin;
  687.  
  688. public GlyphButton(Component parent, Part part) {
  689. XPStyle2 xp = getXP();
  690. skin = xp != null ? xp.getSkin(parent, part) : null;
  691. setBorder(null);
  692. setContentAreaFilled(false);
  693. setMinimumSize(new Dimension(5, 5));
  694. setPreferredSize(new Dimension(16, 16));
  695. setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
  696. }
  697.  
  698. public boolean isFocusTraversable() {
  699. return false;
  700. }
  701.  
  702. protected State getState() {
  703. State state = State.NORMAL;
  704. if (!isEnabled()) {
  705. state = State.DISABLED;
  706. } else if (getModel().isPressed()) {
  707. state = State.PRESSED;
  708. } else if (getModel().isRollover()) {
  709. state = State.HOT;
  710. }
  711. return state;
  712. }
  713.  
  714. public void paintComponent(Graphics g) {
  715. if (XPStyle2.getXP() == null || skin == null) {
  716. return;
  717. }
  718. Dimension d = getSize();
  719. skin.paintSkin(g, 0, 0, d.width, d.height, getState());
  720. }
  721.  
  722. public void setPart(Component parent, Part part) {
  723. XPStyle2 xp = getXP();
  724. skin = xp != null ? xp.getSkin(parent, part) : null;
  725. revalidate();
  726. repaint();
  727. }
  728.  
  729. protected void paintBorder(Graphics g) {
  730. }
  731.  
  732.  
  733. }
  734.  
  735. // Private constructor
  736. private XPStyle2() {
  737. flatMenus = getSysBoolean(Prop.FLATMENUS);
  738.  
  739. colorMap = new HashMap<String, Color>();
  740. borderMap = new HashMap<String, Border>();
  741. // Note: All further access to the maps must be synchronized
  742. }
  743.  
  744.  
  745. private boolean getBoolean(Component c, Part part, State state, Prop prop) {
  746. return ThemeReader.getBoolean(part.getControlName(c), part.getValue(),
  747. State.getValue(part, state),
  748. prop.getValue());
  749. }
  750.  
  751.  
  752.  
  753. static Dimension getPartSize(Part part, State state) {
  754. return ThemeReader.getPartSize(part.getControlName(null), part.getValue(),
  755. State.getValue(part, state));
  756. }
  757.  
  758. private static boolean getSysBoolean(Prop prop) {
  759. // We can use any widget name here, I guess.
  760. return ThemeReader.getSysBoolean("window", prop.getValue());
  761. }
  762. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement