1. /*
  2. * @(#)GTKIconFactory.java 1.22 04/01/13
  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.gtk;
  8. import java.awt.*;
  9. import java.lang.reflect.*;
  10. import javax.swing.*;
  11. import javax.swing.plaf.*;
  12. import java.util.HashMap;
  13. /**
  14. * @version 1.22, 01/13/04
  15. */
  16. class GTKIconFactory {
  17. // Tree icons
  18. private static SynthIcon expandedIcon;
  19. private static SynthIcon collapsedIcon;
  20. private static SynthIcon radioButtonIcon;
  21. private static SynthIcon checkBoxIcon;
  22. private static SynthIcon menuArrowIcon;
  23. private static SynthIcon menuCheckIcon;
  24. private static SynthIcon menuItemArrowIcon;
  25. private static SynthIcon menuItemCheckIcon;
  26. private static SynthIcon checkBoxMenuItemArrowIcon;
  27. private static SynthIcon checkBoxMenuItemCheckIcon;
  28. private static SynthIcon radioButtonMenuItemArrowIcon;
  29. private static SynthIcon radioButtonMenuItemCheckIcon;
  30. //
  31. // Tree methods
  32. //
  33. public static SynthIcon getTreeExpandedIcon() {
  34. if (expandedIcon == null) {
  35. expandedIcon =
  36. new SynthExpanderIcon("paintTreeExpandedIcon");
  37. }
  38. return expandedIcon;
  39. }
  40. public static void paintTreeExpandedIcon(SynthContext context, Graphics g,
  41. int x, int y, int w, int h) {
  42. ((GTKStyle)context.getStyle()).getEngine(context).paintExpander(
  43. context, g, GTKLookAndFeel.synthStateToGTKState(
  44. context.getRegion(), context.getComponentState()),
  45. GTKConstants.EXPANDER_EXPANDED, "treeview", x, y, w, h);
  46. }
  47. public static SynthIcon getTreeCollapsedIcon() {
  48. if (collapsedIcon == null) {
  49. collapsedIcon =
  50. new SynthExpanderIcon("paintTreeCollapsedIcon");
  51. }
  52. return collapsedIcon;
  53. }
  54. public static void paintTreeCollapsedIcon(SynthContext context, Graphics g,
  55. int x, int y, int w, int h) {
  56. ((GTKStyle)context.getStyle()).getEngine(context).paintExpander(
  57. context, g, GTKLookAndFeel.synthStateToGTKState(
  58. context.getRegion(), context.getComponentState()),
  59. GTKConstants.EXPANDER_COLLAPSED, "treeview", x, y, w, h);
  60. }
  61. //
  62. // Radio button
  63. //
  64. public static SynthIcon getRadioButtonIcon() {
  65. if (radioButtonIcon == null) {
  66. radioButtonIcon = new DelegatingIcon("paintRadioButtonIcon",
  67. 13, 13);
  68. }
  69. return radioButtonIcon;
  70. }
  71. public static void paintRadioButtonIcon(SynthContext context, Graphics g,
  72. int x, int y, int w, int h) {
  73. GTKStyle style = (GTKStyle)context.getStyle();
  74. int state = context.getComponentState();
  75. int gtkState = GTKLookAndFeel.synthStateToGTKState(context.getRegion(),
  76. state);
  77. int shadowType = GTKConstants.SHADOW_OUT;
  78. // RadioButton painting appears to be special cased to pass
  79. // SELECTED into the engine even though text colors are PRESSED.
  80. if ((state & SynthConstants.SELECTED) != 0) {
  81. gtkState = SynthConstants.SELECTED;
  82. }
  83. if (gtkState == SynthConstants.SELECTED) {
  84. shadowType = GTKConstants.SHADOW_IN;
  85. }
  86. ((GTKStyle)context.getStyle()).getEngine(
  87. context).paintOption(context, g, gtkState, shadowType,
  88. "radiobutton", x, y, w, h);
  89. }
  90. //
  91. // CheckBox
  92. //
  93. public static SynthIcon getCheckBoxIcon() {
  94. if (checkBoxIcon == null) {
  95. checkBoxIcon = new DelegatingIcon("paintCheckBoxIcon", 13, 13);
  96. }
  97. return checkBoxIcon;
  98. }
  99. public static void paintCheckBoxIcon(SynthContext context, Graphics g,
  100. int x, int y, int w, int h) {
  101. GTKStyle style = (GTKStyle)context.getStyle();
  102. int state = context.getComponentState();
  103. int shadowType = GTKConstants.SHADOW_OUT;
  104. if (((JCheckBox)context.getComponent()).isSelected()) {
  105. shadowType = GTKConstants.SHADOW_IN;
  106. }
  107. ((GTKStyle)context.getStyle()).getEngine(
  108. context).paintCheck(context, g,
  109. GTKLookAndFeel.synthStateToGTKState(context.getRegion(),
  110. context.getComponentState()), shadowType, "checkbutton",
  111. x, y, w, h);
  112. }
  113. //
  114. // Menus
  115. //
  116. public static SynthIcon getMenuArrowIcon() {
  117. if (menuArrowIcon == null) {
  118. menuArrowIcon = new DelegatingIcon("paintMenuArrowIcon", 13, 13);
  119. }
  120. return menuArrowIcon;
  121. }
  122. public static void paintMenuArrowIcon(SynthContext context, Graphics g,
  123. int x, int y, int w, int h) {
  124. GTKStyle style = (GTKStyle)context.getStyle();
  125. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  126. context.getRegion(), context.getComponentState());
  127. int shadow = GTKConstants.SHADOW_OUT;
  128. if (gtkState == SynthConstants.MOUSE_OVER) {
  129. shadow = GTKConstants.SHADOW_IN;
  130. }
  131. int arrowDir;
  132. if (context.getComponent().getComponentOrientation().isLeftToRight()) {
  133. arrowDir = GTKConstants.ARROW_RIGHT;
  134. }
  135. else {
  136. arrowDir = GTKConstants.ARROW_LEFT;
  137. }
  138. style.getEngine(context).paintArrow(context, g, gtkState,
  139. shadow, arrowDir, "menuitem", x + 3, y + 3, 7, 7);
  140. }
  141. public static SynthIcon getMenuItemArrowIcon() {
  142. if (menuItemArrowIcon == null) {
  143. menuItemArrowIcon = new DelegatingIcon("paintMenuItemArrowIcon",
  144. 13, 13);
  145. }
  146. return menuItemArrowIcon;
  147. }
  148. public static void paintMenuItemArrowIcon(SynthContext context, Graphics g,
  149. int x, int y, int w, int h) {
  150. // Don't paint anything. We are just reserving space so we align the
  151. // menu items correctly.
  152. }
  153. public static SynthIcon getCheckBoxMenuItemArrowIcon() {
  154. if (checkBoxMenuItemArrowIcon == null) {
  155. checkBoxMenuItemArrowIcon = new DelegatingIcon(
  156. "paintCheckBoxMenuItemArrowIcon", 13, 13);
  157. }
  158. return checkBoxMenuItemArrowIcon;
  159. }
  160. public static void paintCheckBoxMenuItemArrowIcon(SynthContext context,
  161. Graphics g, int x, int y, int w, int h) {
  162. // Don't paint anything. We are just reserving space so we align the
  163. // menu items correctly.
  164. }
  165. public static SynthIcon getCheckBoxMenuItemCheckIcon() {
  166. if (checkBoxMenuItemCheckIcon == null) {
  167. checkBoxMenuItemCheckIcon = new DelegatingIcon(
  168. "paintCheckBoxMenuItemCheckIcon", 13, 13);
  169. }
  170. return checkBoxMenuItemCheckIcon;
  171. }
  172. public static void paintCheckBoxMenuItemCheckIcon(
  173. SynthContext context, Graphics g, int x, int y, int w, int h) {
  174. GTKStyle style = (GTKStyle)context.getStyle();
  175. int state = context.getComponentState();
  176. int shadowType = GTKConstants.SHADOW_OUT;
  177. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  178. context.getRegion(), state);
  179. if ((state & SynthConstants.MOUSE_OVER) !=0 ) {
  180. gtkState = SynthConstants.MOUSE_OVER;
  181. }
  182. if ((state & SynthConstants.SELECTED) !=0 ) {
  183. shadowType = GTKConstants.SHADOW_IN;
  184. }
  185. style.getEngine(context).paintCheck(context, g, gtkState,
  186. shadowType, "check", x, y, w, h);
  187. }
  188. public static SynthIcon getRadioButtonMenuItemArrowIcon() {
  189. if (radioButtonMenuItemArrowIcon == null) {
  190. radioButtonMenuItemArrowIcon = new DelegatingIcon(
  191. "paintRadioButtonMenuItemArrowIcon", 13, 13);
  192. }
  193. return radioButtonMenuItemArrowIcon;
  194. }
  195. public static void paintRadioButtonMenuItemArrowIcon(SynthContext context,
  196. Graphics g, int x, int y, int w, int h) {
  197. // Don't paint anything. We are just reserving space so we align the
  198. // menu items correctly.
  199. }
  200. public static SynthIcon getRadioButtonMenuItemCheckIcon() {
  201. if (radioButtonMenuItemCheckIcon == null) {
  202. radioButtonMenuItemCheckIcon = new DelegatingIcon(
  203. "paintRadioButtonMenuItemCheckIcon", 13, 13);
  204. }
  205. return radioButtonMenuItemCheckIcon;
  206. }
  207. public static void paintRadioButtonMenuItemCheckIcon(
  208. SynthContext context, Graphics g, int x, int y, int w, int h) {
  209. GTKStyle style = (GTKStyle)context.getStyle();
  210. int state = context.getComponentState();
  211. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  212. context.getRegion(), state);
  213. if ((state & SynthConstants.MOUSE_OVER) != 0) {
  214. gtkState = SynthConstants.MOUSE_OVER;
  215. }
  216. int shadowType = GTKConstants.SHADOW_OUT;
  217. if ((state & SynthConstants.SELECTED) != 0) {
  218. shadowType = GTKConstants.SHADOW_IN;
  219. }
  220. ((GTKStyle)context.getStyle()).getEngine(
  221. context).paintOption(context, g, gtkState, shadowType,
  222. "option", x, y, w, h);
  223. }
  224. //
  225. // ToolBar Handle
  226. //
  227. public static SynthIcon getToolBarHandleIcon() {
  228. return new ToolBarHandleIcon();
  229. }
  230. public static void paintToolBarHandleIcon(SynthContext context,
  231. Graphics g, int x, int y, int w, int h) {
  232. int orientation =
  233. ((JToolBar)context.getComponent()).getOrientation() ==
  234. JToolBar.HORIZONTAL ?
  235. GTKConstants.HORIZONTAL : GTKConstants.VERTICAL;
  236. GTKStyle style = (GTKStyle)context.getStyle();
  237. int gtkState = GTKLookAndFeel.synthStateToGTKState(
  238. context.getRegion(), context.getComponentState());
  239. style.getEngine(context).paintHandle(context, g, gtkState,
  240. GTKConstants.SHADOW_OUT, "handlebox", x, y, w, h,
  241. orientation);
  242. }
  243. private static class DelegatingIcon extends SynthIcon implements
  244. UIResource {
  245. private static final Class[] PARAM_TYPES = new Class[] {
  246. SynthContext.class, Graphics.class, int.class, int.class,
  247. int.class, int.class };
  248. private int width;
  249. private int height;
  250. private Object method;
  251. DelegatingIcon(String methodName, int width, int height) {
  252. this.method = methodName;
  253. this.width = width;
  254. this.height = height;
  255. }
  256. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  257. int w, int h) {
  258. if (context != null) {
  259. try {
  260. getMethod().invoke(GTKIconFactory.class, new Object[] {
  261. context, g, new Integer(x), new Integer(y),
  262. new Integer(w), new Integer(h) });
  263. } catch (IllegalAccessException iae) {
  264. } catch (InvocationTargetException ite) {
  265. }
  266. }
  267. }
  268. public int getIconWidth(SynthContext context) {
  269. return width;
  270. }
  271. public int getIconHeight(SynthContext context) {
  272. return height;
  273. }
  274. private Method getMethod() {
  275. if (method instanceof String) {
  276. Method[] methods = GTKIconFactory.class.getMethods();
  277. try {
  278. method = GTKIconFactory.class.getMethod((String)method,
  279. PARAM_TYPES);
  280. } catch (NoSuchMethodException nsme) {
  281. System.out.println("NSME: " + nsme);
  282. }
  283. }
  284. return (Method)method;
  285. }
  286. }
  287. private static class SynthExpanderIcon extends SynthIcon {
  288. private static final Class[] PARAM_TYPES = new Class[] {
  289. SynthContext.class, Graphics.class, int.class, int.class,
  290. int.class, int.class };
  291. private int width = -1;
  292. private int height = -1;
  293. private Object method;
  294. SynthExpanderIcon(String method) {
  295. this.method = method;
  296. }
  297. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  298. int w, int h) {
  299. if (context != null) {
  300. try {
  301. getMethod().invoke(GTKIconFactory.class, new Object[] {
  302. context, g, new Integer(x), new Integer(y),
  303. new Integer(w), new Integer(h) });
  304. } catch (IllegalAccessException iae) {
  305. } catch (InvocationTargetException ite) {
  306. }
  307. }
  308. }
  309. public int getIconWidth(SynthContext context) {
  310. if (width == -1) {
  311. width = context.getStyle().getInt(context,
  312. "Tree.expanderSize", 10);
  313. }
  314. return width;
  315. }
  316. public int getIconHeight(SynthContext context) {
  317. if (height == -1) {
  318. height = context.getStyle().getInt(context,
  319. "Tree.expanderSize", 10);
  320. }
  321. return height;
  322. }
  323. private Method getMethod() {
  324. if (method instanceof String) {
  325. Method[] methods = GTKIconFactory.class.getMethods();
  326. try {
  327. method = GTKIconFactory.class.getMethod((String)method,
  328. PARAM_TYPES);
  329. } catch (NoSuchMethodException nsme) {
  330. System.out.println("NSME: " + nsme);
  331. }
  332. }
  333. return (Method)method;
  334. }
  335. }
  336. // GTK has a separate widget for the handle box, to mirror this
  337. // we create a unique icon per ToolBar and lookup the style for the
  338. // HandleBox.
  339. private static class ToolBarHandleIcon extends SynthIcon {
  340. private SynthStyle style;
  341. public void paintIcon(SynthContext context, Graphics g, int x, int y,
  342. int w, int h) {
  343. if (context != null) {
  344. context = getContext(context);
  345. paintToolBarHandleIcon(context, g, x, y, w, h);
  346. context.dispose();
  347. }
  348. }
  349. public int getIconWidth(SynthContext context) {
  350. if (((JToolBar)context.getComponent()).getOrientation() ==
  351. JToolBar.HORIZONTAL) {
  352. return 10;
  353. } else {
  354. return context.getComponent().getWidth();
  355. }
  356. }
  357. public int getIconHeight(SynthContext context) {
  358. if (((JToolBar)context.getComponent()).getOrientation() ==
  359. JToolBar.HORIZONTAL) {
  360. return context.getComponent().getHeight();
  361. } else {
  362. return 10;
  363. }
  364. }
  365. private SynthContext getContext(SynthContext context) {
  366. if (style == null) {
  367. style = SynthLookAndFeel.getStyleFactory().getStyle(
  368. context.getComponent(), GTKRegion.HANDLE_BOX);
  369. }
  370. return SynthContext.getContext(SynthContext.class,
  371. context.getComponent(), GTKRegion.HANDLE_BOX,
  372. style, SynthConstants.ENABLED);
  373. }
  374. }
  375. }