1. /*
  2. * @(#)WindowsIconFactory.java 1.21 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.windows;
  8. import javax.swing.*;
  9. import javax.swing.plaf.UIResource;
  10. import java.awt.*;
  11. import java.io.Serializable;
  12. /**
  13. * Factory object that can vend Icons appropriate for the Windows L & F.
  14. * <p>
  15. * <strong>Warning:</strong>
  16. * Serialized objects of this class will not be compatible with
  17. * future Swing releases. The current serialization support is appropriate
  18. * for short term storage or RMI between applications running the same
  19. * version of Swing. A future release of Swing will provide support for
  20. * long term persistence.
  21. *
  22. * @version 1.21 12/19/03
  23. * @author David Kloba
  24. * @author Georges Saab
  25. * @author Rich Schiavi
  26. */
  27. public class WindowsIconFactory implements Serializable
  28. {
  29. private static Icon frame_closeIcon;
  30. private static Icon frame_iconifyIcon;
  31. private static Icon frame_maxIcon;
  32. private static Icon frame_minIcon;
  33. private static Icon frame_resizeIcon;
  34. private static Icon checkBoxIcon;
  35. private static Icon radioButtonIcon;
  36. private static Icon checkBoxMenuItemIcon;
  37. private static Icon radioButtonMenuItemIcon;
  38. private static Icon menuItemCheckIcon;
  39. private static Icon menuItemArrowIcon;
  40. private static Icon menuArrowIcon;
  41. public static Icon getMenuItemCheckIcon() {
  42. if (menuItemCheckIcon == null) {
  43. menuItemCheckIcon = new MenuItemCheckIcon();
  44. }
  45. return menuItemCheckIcon;
  46. }
  47. public static Icon getMenuItemArrowIcon() {
  48. if (menuItemArrowIcon == null) {
  49. menuItemArrowIcon = new MenuItemArrowIcon();
  50. }
  51. return menuItemArrowIcon;
  52. }
  53. public static Icon getMenuArrowIcon() {
  54. if (menuArrowIcon == null) {
  55. menuArrowIcon = new MenuArrowIcon();
  56. }
  57. return menuArrowIcon;
  58. }
  59. public static Icon getCheckBoxIcon() {
  60. if (checkBoxIcon == null) {
  61. checkBoxIcon = new CheckBoxIcon();
  62. }
  63. return checkBoxIcon;
  64. }
  65. public static Icon getRadioButtonIcon() {
  66. if (radioButtonIcon == null) {
  67. radioButtonIcon = new RadioButtonIcon();
  68. }
  69. return radioButtonIcon;
  70. }
  71. public static Icon getCheckBoxMenuItemIcon() {
  72. if (checkBoxMenuItemIcon == null) {
  73. checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
  74. }
  75. return checkBoxMenuItemIcon;
  76. }
  77. public static Icon getRadioButtonMenuItemIcon() {
  78. if (radioButtonMenuItemIcon == null) {
  79. radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
  80. }
  81. return radioButtonMenuItemIcon;
  82. }
  83. public static Icon createFrameCloseIcon() {
  84. if (frame_closeIcon == null) {
  85. frame_closeIcon = new FrameButtonIcon("window.closebutton");
  86. }
  87. return frame_closeIcon;
  88. }
  89. public static Icon createFrameIconifyIcon() {
  90. if (frame_iconifyIcon == null) {
  91. frame_iconifyIcon = new FrameButtonIcon("window.minbutton");
  92. }
  93. return frame_iconifyIcon;
  94. }
  95. public static Icon createFrameMaximizeIcon() {
  96. if (frame_maxIcon == null) {
  97. frame_maxIcon = new FrameButtonIcon("window.maxbutton");
  98. }
  99. return frame_maxIcon;
  100. }
  101. public static Icon createFrameMinimizeIcon() {
  102. if (frame_minIcon == null) {
  103. frame_minIcon = new FrameButtonIcon("window.restorebutton");
  104. }
  105. return frame_minIcon;
  106. }
  107. public static Icon createFrameResizeIcon() {
  108. if(frame_resizeIcon == null)
  109. frame_resizeIcon = new ResizeIcon();
  110. return frame_resizeIcon;
  111. }
  112. private static class FrameButtonIcon implements Icon, Serializable {
  113. private String category;
  114. private FrameButtonIcon(String category) {
  115. this.category = category;
  116. }
  117. public void paintIcon(Component c, Graphics g, int x0, int y0) {
  118. int width = getIconWidth();
  119. int height = getIconHeight();
  120. XPStyle xp = XPStyle.getXP();
  121. if (xp != null) {
  122. XPStyle.Skin skin = xp.getSkin(category);
  123. JButton b = (JButton)c;
  124. ButtonModel model = b.getModel();
  125. int index = 0;
  126. if (!model.isEnabled()) {
  127. index = 3;
  128. } else if (model.isArmed() && model.isPressed()) {
  129. index = 2;
  130. } else if (model.isRollover()) {
  131. index = 1;
  132. }
  133. // Find out if frame is inactive
  134. JInternalFrame jif = (JInternalFrame)SwingUtilities.
  135. getAncestorOfClass(JInternalFrame.class, b);
  136. if (jif != null && !jif.isSelected()) {
  137. index += 4;
  138. }
  139. skin.paintSkin(g, 0, 0, width, height, index);
  140. } else {
  141. g.setColor(Color.black);
  142. int x = width / 12 + 2;
  143. int y = height / 5;
  144. int h = height - y * 2 - 1;
  145. int w = width * 3/4 -3;
  146. int thickness2 = Math.max(height / 8, 2);
  147. int thickness = Math.max(width / 15, 1);
  148. if (category == "window.closebutton") {
  149. int lineWidth;
  150. if (width > 47) lineWidth = 6;
  151. else if (width > 37) lineWidth = 5;
  152. else if (width > 26) lineWidth = 4;
  153. else if (width > 16) lineWidth = 3;
  154. else if (width > 12) lineWidth = 2;
  155. else lineWidth = 1;
  156. y = height / 12 + 2;
  157. if (lineWidth == 1) {
  158. if (w % 2 == 1) { x++; w++; }
  159. g.drawLine(x, y, x+w-2, y+w-2);
  160. g.drawLine(x+w-2, y, x, y+w-2);
  161. } else if (lineWidth == 2) {
  162. if (w > 6) { x++; w--; }
  163. g.drawLine(x, y, x+w-2, y+w-2);
  164. g.drawLine(x+w-2, y, x, y+w-2);
  165. g.drawLine(x+1, y, x+w-1, y+w-2);
  166. g.drawLine(x+w-1, y, x+1, y+w-2);
  167. } else {
  168. x += 2; y++; w -= 2;
  169. g.drawLine(x, y, x+w-1, y+w-1);
  170. g.drawLine(x+w-1, y, x, y+w-1);
  171. g.drawLine(x+1, y, x+w-1, y+w-2);
  172. g.drawLine(x+w-2, y, x, y+w-2);
  173. g.drawLine(x, y+1, x+w-2, y+w-1);
  174. g.drawLine(x+w-1, y+1, x+1, y+w-1);
  175. for (int i = 4; i <= lineWidth; i++) {
  176. g.drawLine(x+i-2, y, x+w-1, y+w-i+1);
  177. g.drawLine(x, y+i-2, x+w-i+1, y+w-1);
  178. g.drawLine(x+w-i+1, y, x, y+w-i+1);
  179. g.drawLine(x+w-1, y+i-2, x+i-2, y+w-1);
  180. }
  181. }
  182. } else if (category == "window.minbutton") {
  183. g.fillRect(x, y+h-thickness2, w-w3, thickness2);
  184. } else if (category == "window.maxbutton") {
  185. g.fillRect(x, y, w, thickness2);
  186. g.fillRect(x, y, thickness, h);
  187. g.fillRect(x+w-thickness, y, thickness, h);
  188. g.fillRect(x, y+h-thickness, w, thickness);
  189. } else if (category == "window.restorebutton") {
  190. g.fillRect(x+w3, y, w-w3, thickness2);
  191. g.fillRect(x+w3, y, thickness, h3);
  192. g.fillRect(x+w-thickness, y, thickness, h-h3);
  193. g.fillRect(x+w-w3, y+h-h3-thickness, w3, thickness);
  194. g.fillRect(x, y+h3, w-w3, thickness2);
  195. g.fillRect(x, y+h3, thickness, h-h3);
  196. g.fillRect(x+w-w3-thickness, y+h3, thickness, h-h3);
  197. g.fillRect(x, y+h-thickness, w-w3, thickness);
  198. }
  199. }
  200. }
  201. public int getIconWidth() {
  202. int width;
  203. if (XPStyle.getXP() != null) {
  204. // Fix for XP bug where sometimes these sizes aren't updated properly
  205. // Assume for now that XP buttons are always square
  206. width = UIManager.getInt("InternalFrame.titleButtonHeight") -2;
  207. } else {
  208. width = UIManager.getInt("InternalFrame.titleButtonWidth") -2;
  209. }
  210. if (XPStyle.getXP() != null) {
  211. width -= 2;
  212. }
  213. return width;
  214. }
  215. public int getIconHeight() {
  216. int height = UIManager.getInt("InternalFrame.titleButtonHeight")-4;
  217. return height;
  218. }
  219. }
  220. private static class ResizeIcon implements Icon, Serializable {
  221. public void paintIcon(Component c, Graphics g, int x, int y) {
  222. g.setColor(UIManager.getColor("InternalFrame.resizeIconHighlight"));
  223. g.drawLine(0, 11, 11, 0);
  224. g.drawLine(4, 11, 11, 4);
  225. g.drawLine(8, 11, 11, 8);
  226. g.setColor(UIManager.getColor("InternalFrame.resizeIconShadow"));
  227. g.drawLine(1, 11, 11, 1);
  228. g.drawLine(2, 11, 11, 2);
  229. g.drawLine(5, 11, 11, 5);
  230. g.drawLine(6, 11, 11, 6);
  231. g.drawLine(9, 11, 11, 9);
  232. g.drawLine(10, 11, 11, 10);
  233. }
  234. public int getIconWidth() { return 13; }
  235. public int getIconHeight() { return 13; }
  236. };
  237. private static class CheckBoxIcon implements Icon, Serializable
  238. {
  239. final static int csize = 13;
  240. public void paintIcon(Component c, Graphics g, int x, int y) {
  241. JCheckBox cb = (JCheckBox) c;
  242. ButtonModel model = cb.getModel();
  243. XPStyle xp = XPStyle.getXP();
  244. if (xp != null) {
  245. int index = 0;
  246. if (!model.isEnabled()) {
  247. index = 3; // disabled
  248. } else if (model.isPressed() && model.isArmed()) {
  249. index = 2; // pressed
  250. } else if (model.isRollover()) {
  251. index = 1; // rollover
  252. }
  253. if (model.isSelected()) {
  254. index += 4;
  255. }
  256. xp.getSkin("button.checkbox").paintSkin(g, x, y, index);
  257. } else {
  258. // outer bevel
  259. if(!cb.isBorderPaintedFlat()) {
  260. // Outer top/left
  261. g.setColor(UIManager.getColor("CheckBox.shadow"));
  262. g.drawLine(x, y, x+11, y);
  263. g.drawLine(x, y+1, x, y+11);
  264. // Outer bottom/right
  265. g.setColor(UIManager.getColor("CheckBox.highlight"));
  266. g.drawLine(x+12, y, x+12, y+12);
  267. g.drawLine(x, y+12, x+11, y+12);
  268. // Inner top.left
  269. g.setColor(UIManager.getColor("CheckBox.darkShadow"));
  270. g.drawLine(x+1, y+1, x+10, y+1);
  271. g.drawLine(x+1, y+2, x+1, y+10);
  272. // Inner bottom/right
  273. g.setColor(UIManager.getColor("CheckBox.light"));
  274. g.drawLine(x+1, y+11, x+11, y+11);
  275. g.drawLine(x+11, y+1, x+11, y+10);
  276. // inside box
  277. if((model.isPressed() && model.isArmed()) || !model.isEnabled()) {
  278. g.setColor(UIManager.getColor("CheckBox.background"));
  279. } else {
  280. g.setColor(UIManager.getColor("CheckBox.interiorBackground"));
  281. }
  282. g.fillRect(x+2, y+2, csize-4, csize-4);
  283. } else {
  284. g.setColor(UIManager.getColor("CheckBox.shadow"));
  285. g.drawRect(x+1, y+1, csize-3, csize-3);
  286. if((model.isPressed() && model.isArmed()) || !model.isEnabled()) {
  287. g.setColor(UIManager.getColor("CheckBox.background"));
  288. } else {
  289. g.setColor(UIManager.getColor("CheckBox.interiorBackground"));
  290. }
  291. g.fillRect(x+2, y+2, csize-4, csize-4);
  292. }
  293. if(model.isEnabled()) {
  294. g.setColor(UIManager.getColor("CheckBox.darkShadow"));
  295. } else {
  296. g.setColor(UIManager.getColor("CheckBox.shadow"));
  297. }
  298. // paint check
  299. if (model.isSelected()) {
  300. g.drawLine(x+9, y+3, x+9, y+3);
  301. g.drawLine(x+8, y+4, x+9, y+4);
  302. g.drawLine(x+7, y+5, x+9, y+5);
  303. g.drawLine(x+6, y+6, x+8, y+6);
  304. g.drawLine(x+3, y+7, x+7, y+7);
  305. g.drawLine(x+4, y+8, x+6, y+8);
  306. g.drawLine(x+5, y+9, x+5, y+9);
  307. g.drawLine(x+3, y+5, x+3, y+5);
  308. g.drawLine(x+3, y+6, x+4, y+6);
  309. }
  310. }
  311. }
  312. public int getIconWidth() {
  313. XPStyle xp = XPStyle.getXP();
  314. if (xp != null) {
  315. return xp.getSkin("button.checkbox").getWidth();
  316. } else {
  317. return csize;
  318. }
  319. }
  320. public int getIconHeight() {
  321. XPStyle xp = XPStyle.getXP();
  322. if (xp != null) {
  323. return xp.getSkin("button.checkbox").getHeight();
  324. } else {
  325. return csize;
  326. }
  327. }
  328. }
  329. private static class RadioButtonIcon implements Icon, UIResource, Serializable
  330. {
  331. public void paintIcon(Component c, Graphics g, int x, int y) {
  332. AbstractButton b = (AbstractButton) c;
  333. ButtonModel model = b.getModel();
  334. XPStyle xp = XPStyle.getXP();
  335. if (xp != null) {
  336. XPStyle.Skin skin = xp.getSkin("button.radiobutton");
  337. int index = 0;
  338. if (!model.isEnabled()) {
  339. index = 3; // disabled
  340. } else if (model.isPressed() && model.isArmed()) {
  341. index = 2; // pressed
  342. } else if (model.isRollover()) {
  343. index = 1; // rollover
  344. }
  345. if (model.isSelected()) {
  346. index += 4;
  347. }
  348. skin.paintSkin(g, x, y, index);
  349. } else {
  350. // fill interior
  351. if((model.isPressed() && model.isArmed()) || !model.isEnabled()) {
  352. g.setColor(UIManager.getColor("RadioButton.background"));
  353. } else {
  354. g.setColor(UIManager.getColor("RadioButton.interiorBackground"));
  355. }
  356. g.fillRect(x+2, y+2, 8, 8);
  357. // outter left arc
  358. g.setColor(UIManager.getColor("RadioButton.shadow"));
  359. g.drawLine(x+4, y+0, x+7, y+0);
  360. g.drawLine(x+2, y+1, x+3, y+1);
  361. g.drawLine(x+8, y+1, x+9, y+1);
  362. g.drawLine(x+1, y+2, x+1, y+3);
  363. g.drawLine(x+0, y+4, x+0, y+7);
  364. g.drawLine(x+1, y+8, x+1, y+9);
  365. // outter right arc
  366. g.setColor(UIManager.getColor("RadioButton.highlight"));
  367. g.drawLine(x+2, y+10, x+3, y+10);
  368. g.drawLine(x+4, y+11, x+7, y+11);
  369. g.drawLine(x+8, y+10, x+9, y+10);
  370. g.drawLine(x+10, y+9, x+10, y+8);
  371. g.drawLine(x+11, y+7, x+11, y+4);
  372. g.drawLine(x+10, y+3, x+10, y+2);
  373. // inner left arc
  374. g.setColor(UIManager.getColor("RadioButton.darkShadow"));
  375. g.drawLine(x+4, y+1, x+7, y+1);
  376. g.drawLine(x+2, y+2, x+3, y+2);
  377. g.drawLine(x+8, y+2, x+9, y+2);
  378. g.drawLine(x+2, y+3, x+2, y+3);
  379. g.drawLine(x+1, y+4, x+1, y+7);
  380. g.drawLine(x+2, y+8, x+2, y+8);
  381. // inner right arc
  382. g.setColor(UIManager.getColor("RadioButton.light"));
  383. g.drawLine(x+2, y+9, x+3, y+9);
  384. g.drawLine(x+4, y+10, x+7, y+10);
  385. g.drawLine(x+8, y+9, x+9, y+9);
  386. g.drawLine(x+9, y+8, x+9, y+8);
  387. g.drawLine(x+10, y+7, x+10, y+4);
  388. g.drawLine(x+9, y+3, x+9, y+3);
  389. // indicate whether selected or not
  390. if(model.isSelected()) {
  391. g.setColor(UIManager.getColor("RadioButton.darkShadow"));
  392. g.fillRect(x+4, y+5, 4, 2);
  393. g.fillRect(x+5, y+4, 2, 4);
  394. }
  395. }
  396. }
  397. public int getIconWidth() {
  398. XPStyle xp = XPStyle.getXP();
  399. if (xp != null) {
  400. return xp.getSkin("button.radiobutton").getWidth();
  401. } else {
  402. return 13;
  403. }
  404. }
  405. public int getIconHeight() {
  406. XPStyle xp = XPStyle.getXP();
  407. if (xp != null) {
  408. return xp.getSkin("button.radiobutton").getHeight();
  409. } else {
  410. return 13;
  411. }
  412. }
  413. } // end class RadioButtonIcon
  414. private static class CheckBoxMenuItemIcon implements Icon, UIResource, Serializable
  415. {
  416. public void paintIcon(Component c, Graphics g, int x, int y) {
  417. AbstractButton b = (AbstractButton) c;
  418. ButtonModel model = b.getModel();
  419. boolean isSelected = model.isSelected();
  420. if (isSelected) {
  421. y = y - getIconHeight() / 2;
  422. g.drawLine(x+9, y+3, x+9, y+3);
  423. g.drawLine(x+8, y+4, x+9, y+4);
  424. g.drawLine(x+7, y+5, x+9, y+5);
  425. g.drawLine(x+6, y+6, x+8, y+6);
  426. g.drawLine(x+3, y+7, x+7, y+7);
  427. g.drawLine(x+4, y+8, x+6, y+8);
  428. g.drawLine(x+5, y+9, x+5, y+9);
  429. g.drawLine(x+3, y+5, x+3, y+5);
  430. g.drawLine(x+3, y+6, x+4, y+6);
  431. }
  432. }
  433. public int getIconWidth() { return 9; }
  434. public int getIconHeight() { return 9; }
  435. } // End class CheckBoxMenuItemIcon
  436. private static class RadioButtonMenuItemIcon implements Icon, UIResource, Serializable
  437. {
  438. public void paintIcon(Component c, Graphics g, int x, int y) {
  439. AbstractButton b = (AbstractButton) c;
  440. ButtonModel model = b.getModel();
  441. if (b.isSelected() == true) {
  442. g.fillArc(0,0,getIconWidth()-2, getIconHeight()-2, 0, 360);
  443. }
  444. }
  445. public int getIconWidth() { return 12; }
  446. public int getIconHeight() { return 12; }
  447. } // End class RadioButtonMenuItemIcon
  448. private static class MenuItemCheckIcon implements Icon, UIResource, Serializable{
  449. public void paintIcon(Component c, Graphics g, int x, int y) {
  450. /* For debugging:
  451. Color oldColor = g.getColor();
  452. g.setColor(Color.orange);
  453. g.fill3DRect(x,y,getIconWidth(), getIconHeight(), true);
  454. g.setColor(oldColor);
  455. */
  456. }
  457. public int getIconWidth() { return 9; }
  458. public int getIconHeight() { return 9; }
  459. } // End class MenuItemCheckIcon
  460. private static class MenuItemArrowIcon implements Icon, UIResource, Serializable {
  461. public void paintIcon(Component c, Graphics g, int x, int y) {
  462. /* For debugging:
  463. Color oldColor = g.getColor();
  464. g.setColor(Color.green);
  465. g.fill3DRect(x,y,getIconWidth(), getIconHeight(), true);
  466. g.setColor(oldColor);
  467. */
  468. }
  469. public int getIconWidth() { return 4; }
  470. public int getIconHeight() { return 8; }
  471. } // End class MenuItemArrowIcon
  472. private static class MenuArrowIcon implements Icon, UIResource, Serializable {
  473. public void paintIcon(Component c, Graphics g, int x, int y) {
  474. g.translate(x,y);
  475. if( WindowsUtils.isLeftToRight(c) ) {
  476. g.drawLine( 0, 0, 0, 7 );
  477. g.drawLine( 1, 1, 1, 6 );
  478. g.drawLine( 2, 2, 2, 5 );
  479. g.drawLine( 3, 3, 3, 4 );
  480. } else {
  481. g.drawLine( 4, 0, 4, 7 );
  482. g.drawLine( 3, 1, 3, 6 );
  483. g.drawLine( 2, 2, 2, 5 );
  484. g.drawLine( 1, 3, 1, 4 );
  485. }
  486. g.translate(-x,-y);
  487. }
  488. public int getIconWidth() { return 4; }
  489. public int getIconHeight() { return 8; }
  490. } // End class MenuArrowIcon
  491. }