1. /*
  2. * @(#)MotifIconFactory.java 1.28 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.motif;
  8. import javax.swing.*;
  9. import javax.swing.plaf.UIResource;
  10. import java.awt.Color;
  11. import java.awt.Component;
  12. import java.awt.Dimension;
  13. import java.awt.Graphics;
  14. import java.awt.Polygon;
  15. import java.io.Serializable;
  16. /**
  17. * Icon factory for the CDE/Motif Look and Feel
  18. * <p>
  19. * <strong>Warning:</strong>
  20. * Serialized objects of this class will not be compatible with
  21. * future Swing releases. The current serialization support is appropriate
  22. * for short term storage or RMI between applications running the same
  23. * version of Swing. A future release of Swing will provide support for
  24. * long term persistence.
  25. *
  26. * 1.20 04/27/99
  27. * @author Georges Saab
  28. */
  29. public class MotifIconFactory implements Serializable
  30. {
  31. private static Icon checkBoxIcon;
  32. private static Icon radioButtonIcon;
  33. private static Icon menuItemCheckIcon;
  34. private static Icon menuItemArrowIcon;
  35. private static Icon menuArrowIcon;
  36. public static Icon getMenuItemCheckIcon() {
  37. if (menuItemCheckIcon == null) {
  38. menuItemCheckIcon = new MenuItemCheckIcon();
  39. }
  40. return menuItemCheckIcon;
  41. }
  42. public static Icon getMenuItemArrowIcon() {
  43. if (menuItemArrowIcon == null) {
  44. menuItemArrowIcon = new MenuItemArrowIcon();
  45. }
  46. return menuItemArrowIcon;
  47. }
  48. public static Icon getMenuArrowIcon() {
  49. if (menuArrowIcon == null) {
  50. menuArrowIcon = new MenuArrowIcon();
  51. }
  52. return menuArrowIcon;
  53. }
  54. public static Icon getCheckBoxIcon() {
  55. if (checkBoxIcon == null) {
  56. checkBoxIcon = new CheckBoxIcon();
  57. }
  58. return checkBoxIcon;
  59. }
  60. public static Icon getRadioButtonIcon() {
  61. if (radioButtonIcon == null) {
  62. radioButtonIcon = new RadioButtonIcon();
  63. }
  64. return radioButtonIcon;
  65. }
  66. private static class CheckBoxIcon implements Icon, UIResource, Serializable {
  67. final static int csize = 13;
  68. private Color control = UIManager.getColor("control");
  69. private Color foreground = UIManager.getColor("CheckBox.foreground");
  70. private Color shadow = UIManager.getColor("controlShadow");
  71. private Color highlight = UIManager.getColor("controlHighlight");
  72. private Color lightShadow = UIManager.getColor("controlLightShadow");
  73. public void paintIcon(Component c, Graphics g, int x, int y) {
  74. AbstractButton b = (AbstractButton) c;
  75. ButtonModel model = b.getModel();
  76. boolean flat = false;
  77. if(b instanceof JCheckBox) {
  78. flat = ((JCheckBox)b).isBorderPaintedFlat();
  79. }
  80. boolean isPressed = model.isPressed();
  81. boolean isArmed = model.isArmed();
  82. boolean isEnabled = model.isEnabled();
  83. boolean isSelected = model.isSelected();
  84. // There are 4 "looks" to the Motif CheckBox:
  85. // drawCheckBezelOut - default unchecked state
  86. // drawBezel - when we uncheck in toggled state
  87. // drawCheckBezel - when we check in toggle state
  88. // drawCheckBezelIn - selected, mouseReleased
  89. boolean checkToggleIn = ((isPressed &&
  90. !isArmed &&
  91. isSelected) ||
  92. (isPressed &&
  93. isArmed &&
  94. !isSelected));
  95. boolean uncheckToggleOut = ((isPressed &&
  96. !isArmed &&
  97. !isSelected) ||
  98. (isPressed &&
  99. isArmed &&
  100. isSelected));
  101. boolean checkIn = (!isPressed &&
  102. isArmed &&
  103. isSelected ||
  104. (!isPressed &&
  105. !isArmed &&
  106. isSelected));
  107. if(flat) {
  108. g.setColor(shadow);
  109. g.drawRect(x+2,y,csize-1,csize-1);
  110. if(uncheckToggleOut || checkToggleIn) {
  111. g.setColor(control);
  112. g.fillRect(x+3,y+1,csize-2,csize-2);
  113. }
  114. }
  115. // Padding required to keep focus highlight from intersecting icon.
  116. x += (MotifGraphicsUtils.isLeftToRight(c)) ? 2 : -3;
  117. if (checkToggleIn) {
  118. // toggled from unchecked to checked
  119. drawCheckBezel(g,x,y,csize,true,false,false,flat);
  120. } else if (uncheckToggleOut) {
  121. // MotifBorderFactory.drawBezel(g,x,y,csize,csize,false,false);
  122. drawCheckBezel(g,x,y,csize,true,true,false,flat);
  123. } else if (checkIn) {
  124. // show checked, unpressed state
  125. drawCheckBezel(g,x,y,csize,false,false,true,flat);
  126. } else if(!flat) {
  127. // show unchecked state
  128. drawCheckBezelOut(g,x,y,csize);
  129. }
  130. }
  131. public int getIconWidth() {
  132. return csize;
  133. }
  134. public int getIconHeight() {
  135. return csize;
  136. }
  137. public void drawCheckBezelOut(Graphics g, int x, int y, int csize){
  138. Color controlShadow = UIManager.getColor("controlShadow");
  139. int w = csize;
  140. int h = csize;
  141. Color oldColor = g.getColor();
  142. g.translate(x,y);
  143. g.setColor(highlight); // inner 3D border
  144. g.drawLine(0, 0, 0, h-1);
  145. g.drawLine(1, 0, w-1, 0);
  146. g.setColor(shadow); // black drop shadow __|
  147. g.drawLine(1, h-1, w-1, h-1);
  148. g.drawLine(w-1, h-1, w-1, 1);
  149. g.translate(-x,-y);
  150. g.setColor(oldColor);
  151. }
  152. public void drawCheckBezel(Graphics g, int x, int y, int csize,
  153. boolean shade, boolean out, boolean check, boolean flat)
  154. {
  155. Color oldColor = g.getColor();
  156. g.translate(x, y);
  157. //bottom
  158. if(!flat) {
  159. if (out) {
  160. g.setColor(control);
  161. g.fillRect(1,1,csize-2,csize-2);
  162. g.setColor(shadow);
  163. } else {
  164. g.setColor(lightShadow);
  165. g.fillRect(0,0,csize,csize);
  166. g.setColor(highlight);
  167. }
  168. g.drawLine(1,csize-1,csize-2,csize-1);
  169. if (shade) {
  170. g.drawLine(2,csize-2,csize-3,csize-2);
  171. g.drawLine(csize-2,2,csize-2 ,csize-1);
  172. if (out) {
  173. g.setColor(highlight);
  174. } else {
  175. g.setColor(shadow);
  176. }
  177. g.drawLine(1,2,1,csize-2);
  178. g.drawLine(1,1,csize-3,1);
  179. if (out) {
  180. g.setColor(shadow);
  181. } else {
  182. g.setColor(highlight);
  183. }
  184. }
  185. //right
  186. g.drawLine(csize-1,1,csize-1,csize-1);
  187. //left
  188. if (out) {
  189. g.setColor(highlight);
  190. } else {
  191. g.setColor(shadow);
  192. }
  193. g.drawLine(0,1,0,csize-1);
  194. //top
  195. g.drawLine(0,0,csize-1,0);
  196. }
  197. if (check) {
  198. // draw check
  199. g.setColor(foreground);
  200. g.drawLine(csize-2,1,csize-2,2);
  201. g.drawLine(csize-3,2,csize-3,3);
  202. g.drawLine(csize-4,3,csize-4,4);
  203. g.drawLine(csize-5,4,csize-5,6);
  204. g.drawLine(csize-6,5,csize-6,8);
  205. g.drawLine(csize-7,6,csize-7,10);
  206. g.drawLine(csize-8,7,csize-8,10);
  207. g.drawLine(csize-9,6,csize-9,9);
  208. g.drawLine(csize-10,5,csize-10,8);
  209. g.drawLine(csize-11,5,csize-11,7);
  210. g.drawLine(csize-12,6,csize-12,6);
  211. }
  212. g.translate(-x, -y);
  213. g.setColor(oldColor);
  214. }
  215. } // end class CheckBoxIcon
  216. private static class RadioButtonIcon implements Icon, UIResource, Serializable {
  217. private Color dot = UIManager.getColor("activeCaptionBorder");
  218. private Color highlight = UIManager.getColor("controlHighlight");
  219. private Color shadow = UIManager.getColor("controlShadow");
  220. public void paintIcon(Component c, Graphics g, int x, int y) {
  221. // fill interior
  222. AbstractButton b = (AbstractButton) c;
  223. ButtonModel model = b.getModel();
  224. int w = getIconWidth();
  225. int h = getIconHeight();
  226. // add pad so focus isn't smudged on the x
  227. x += (MotifGraphicsUtils.isLeftToRight(c))? 2 : -3;
  228. boolean isPressed = model.isPressed();
  229. boolean isArmed = model.isArmed();
  230. boolean isEnabled = model.isEnabled();
  231. boolean isSelected = model.isSelected();
  232. boolean checkIn = ((isPressed &&
  233. !isArmed &&
  234. isSelected) ||
  235. (isPressed &&
  236. isArmed &&
  237. !isSelected)
  238. ||
  239. (!isPressed &&
  240. isArmed &&
  241. isSelected ||
  242. (!isPressed &&
  243. !isArmed &&
  244. isSelected)));
  245. if (checkIn){
  246. g.setColor(shadow);
  247. g.drawLine(x+5,y+0,x+8,y+0);
  248. g.drawLine(x+3,y+1,x+4,y+1);
  249. g.drawLine(x+9,y+1,x+9,y+1);
  250. g.drawLine(x+2,y+2,x+2,y+2);
  251. g.drawLine(x+1,y+3,x+1,y+3);
  252. g.drawLine(x,y+4,x,y+9);
  253. g.drawLine(x+1,y+10,x+1,y+10);
  254. g.drawLine(x+2,y+11,x+2,y+11);
  255. g.setColor(highlight);
  256. g.drawLine(x+3,y+12,x+4,y+12);
  257. g.drawLine(x+5,y+13,x+8,y+13);
  258. g.drawLine(x+9,y+12,x+10,y+12);
  259. g.drawLine(x+11,y+11,x+11,y+11);
  260. g.drawLine(x+12,y+10,x+12,y+10);
  261. g.drawLine(x+13,y+9,x+13,y+4);
  262. g.drawLine(x+12,y+3,x+12,y+3);
  263. g.drawLine(x+11,y+2,x+11,y+2);
  264. g.drawLine(x+10,y+1,x+10,y+1);
  265. g.setColor(dot);
  266. g.fillRect(x+4,y+5,6,4);
  267. g.drawLine(x+5,y+4,x+8,y+4);
  268. g.drawLine(x+5,y+9,x+8,y+9);
  269. }
  270. else {
  271. g.setColor(highlight);
  272. g.drawLine(x+5,y+0,x+8,y+0);
  273. g.drawLine(x+3,y+1,x+4,y+1);
  274. g.drawLine(x+9,y+1,x+9,y+1);
  275. g.drawLine(x+2,y+2,x+2,y+2);
  276. g.drawLine(x+1,y+3,x+1,y+3);
  277. g.drawLine(x,y+4,x,y+9);
  278. g.drawLine(x+1,y+10,x+1,y+10);
  279. g.drawLine(x+2,y+11,x+2,y+11);
  280. g.setColor(shadow);
  281. g.drawLine(x+3,y+12,x+4,y+12);
  282. g.drawLine(x+5,y+13,x+8,y+13);
  283. g.drawLine(x+9,y+12,x+10,y+12);
  284. g.drawLine(x+11,y+11,x+11,y+11);
  285. g.drawLine(x+12,y+10,x+12,y+10);
  286. g.drawLine(x+13,y+9,x+13,y+4);
  287. g.drawLine(x+12,y+3,x+12,y+3);
  288. g.drawLine(x+11,y+2,x+11,y+2);
  289. g.drawLine(x+10,y+1,x+10,y+1);
  290. }
  291. }
  292. public int getIconWidth() {
  293. return 13;
  294. }
  295. public int getIconHeight() {
  296. return 13;
  297. }
  298. } // end class RadioButtonIcon
  299. private static class MenuItemCheckIcon implements Icon, UIResource, Serializable
  300. {
  301. public void paintIcon(Component c,Graphics g, int x, int y)
  302. {
  303. }
  304. public int getIconWidth() { return 0; }
  305. public int getIconHeight() { return 0; }
  306. } // end class MenuItemCheckIcon
  307. private static class MenuItemArrowIcon implements Icon, UIResource, Serializable
  308. {
  309. public void paintIcon(Component c,Graphics g, int x, int y)
  310. {
  311. }
  312. public int getIconWidth() { return 0; }
  313. public int getIconHeight() { return 0; }
  314. } // end class MenuItemArrowIcon
  315. private static class MenuArrowIcon implements Icon, UIResource, Serializable
  316. {
  317. private Color focus = UIManager.getColor("windowBorder");
  318. private Color shadow = UIManager.getColor("controlShadow");
  319. private Color highlight = UIManager.getColor("controlHighlight");
  320. public void paintIcon(Component c, Graphics g, int x, int y) {
  321. AbstractButton b = (AbstractButton) c;
  322. ButtonModel model = b.getModel();
  323. // These variables are kind of pointless as the following code
  324. // assumes the icon will be 10 x 10 regardless of their value.
  325. int w = getIconWidth();
  326. int h = getIconHeight();
  327. Color oldColor = g.getColor();
  328. if (model.isSelected()){
  329. if( MotifGraphicsUtils.isLeftToRight(c) ){
  330. g.setColor(shadow);
  331. g.fillRect(x+1,y+1,2,h);
  332. g.drawLine(x+4,y+2,x+4,y+2);
  333. g.drawLine(x+6,y+3,x+6,y+3);
  334. g.drawLine(x+8,y+4,x+8,y+5);
  335. g.setColor(focus);
  336. g.fillRect(x+2,y+2,2,h-2);
  337. g.fillRect(x+4,y+3,2,h-4);
  338. g.fillRect(x+6,y+4,2,h-6);
  339. g.setColor(highlight);
  340. g.drawLine(x+2,y+h,x+2,y+h);
  341. g.drawLine(x+4,y+h-1,x+4,y+h-1);
  342. g.drawLine(x+6,y+h-2,x+6,y+h-2);
  343. g.drawLine(x+8,y+h-4,x+8,y+h-3);
  344. } else {
  345. g.setColor(highlight);
  346. g.fillRect(x+7,y+1,2,10);
  347. g.drawLine(x+5,y+9,x+5,y+9);
  348. g.drawLine(x+3,y+8,x+3,y+8);
  349. g.drawLine(x+1,y+6,x+1,y+7);
  350. g.setColor(focus);
  351. g.fillRect(x+6,y+2,2,8);
  352. g.fillRect(x+4,y+3,2,6);
  353. g.fillRect(x+2,y+4,2,4);
  354. g.setColor(shadow);
  355. g.drawLine(x+1,y+4,x+1,y+5);
  356. g.drawLine(x+3,y+3,x+3,y+3);
  357. g.drawLine(x+5,y+2,x+5,y+2);
  358. g.drawLine(x+7,y+1,x+7,y+1);
  359. }
  360. } else {
  361. if( MotifGraphicsUtils.isLeftToRight(c) ){
  362. g.setColor(highlight);
  363. g.drawLine(x+1,y+1,x+1,y+h);
  364. g.drawLine(x+2,y+1,x+2,y+h-2);
  365. g.fillRect(x+3,y+2,2,2);
  366. g.fillRect(x+5,y+3,2,2);
  367. g.fillRect(x+7,y+4,2,2);
  368. g.setColor(shadow);
  369. g.drawLine(x+2,y+h-1,x+2,y+h);
  370. g.fillRect(x+3,y+h-2,2,2);
  371. g.fillRect(x+5,y+h-3,2,2);
  372. g.fillRect(x+7,y+h-4,2,2);
  373. g.setColor(oldColor);
  374. } else {
  375. g.setColor(highlight);
  376. g.fillRect(x+1,y+4,2,2);
  377. g.fillRect(x+3,y+3,2,2);
  378. g.fillRect(x+5,y+2,2,2);
  379. g.drawLine(x+7,y+1,x+7,y+2);
  380. g.setColor(shadow);
  381. g.fillRect(x+1,y+h-4,2,2);
  382. g.fillRect(x+3,y+h-3,2,2);
  383. g.fillRect(x+5,y+h-2,2,2);
  384. g.drawLine(x+7,y+3,x+7,y+h);
  385. g.drawLine(x+8,y+1,x+8,y+h);
  386. g.setColor(oldColor);
  387. }
  388. }
  389. }
  390. public int getIconWidth() { return 10; }
  391. public int getIconHeight() { return 10; }
  392. } // End class MenuArrowIcon
  393. }