1. /*
  2. * @(#)BasicGraphicsUtils.java 1.50 00/07/26
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.plaf.basic;
  11. import javax.swing.*;
  12. import java.awt.Component;
  13. import java.awt.Color;
  14. import java.awt.Dimension;
  15. import java.awt.Font;
  16. import java.awt.FontMetrics;
  17. import java.awt.Graphics;
  18. import java.awt.Insets;
  19. import java.awt.Rectangle;
  20. import java.awt.event.KeyEvent;
  21. /*
  22. * @version 1.44 02/11/99
  23. * @author Hans Muller
  24. */
  25. public class BasicGraphicsUtils
  26. {
  27. private static final Insets GROOVE_INSETS = new Insets(2, 2, 2, 2);
  28. private static final Insets ETCHED_INSETS = new Insets(2, 2, 2, 2);
  29. public static void drawEtchedRect(Graphics g, int x, int y, int w, int h,
  30. Color shadow, Color darkShadow,
  31. Color highlight, Color lightHighlight)
  32. {
  33. Color oldColor = g.getColor(); // Make no net change to g
  34. g.translate(x, y);
  35. g.setColor(shadow);
  36. g.drawLine(0, 0, w-1, 0); // outer border, top
  37. g.drawLine(0, 1, 0, h-2); // outer border, left
  38. g.setColor(darkShadow);
  39. g.drawLine(1, 1, w-3, 1); // inner border, top
  40. g.drawLine(1, 2, 1, h-3); // inner border, left
  41. g.setColor(lightHighlight);
  42. g.drawLine(w-1, 0, w-1, h-1); // outer border, bottom
  43. g.drawLine(0, h-1, w-1, h-1); // outer border, right
  44. g.setColor(highlight);
  45. g.drawLine(w-2, 1, w-2, h-3); // inner border, right
  46. g.drawLine(1, h-2, w-2, h-2); // inner border, bottom
  47. g.translate(-x, -y);
  48. g.setColor(oldColor);
  49. }
  50. /**
  51. * Returns the amount of space taken up by a border drawn by
  52. * <code>drawEtchedRect()</code>
  53. *
  54. * @return the inset of an etched rect
  55. */
  56. public static Insets getEtchedInsets() {
  57. return ETCHED_INSETS;
  58. }
  59. public static void drawGroove(Graphics g, int x, int y, int w, int h,
  60. Color shadow, Color highlight)
  61. {
  62. Color oldColor = g.getColor(); // Make no net change to g
  63. g.translate(x, y);
  64. g.setColor(shadow);
  65. g.drawRect(0, 0, w-2, h-2);
  66. g.setColor(highlight);
  67. g.drawLine(1, h-3, 1, 1);
  68. g.drawLine(1, 1, w-3, 1);
  69. g.drawLine(0, h-1, w-1, h-1);
  70. g.drawLine(w-1, h-1, w-1, 0);
  71. g.translate(-x, -y);
  72. g.setColor(oldColor);
  73. }
  74. /**
  75. * Returns the amount of space taken up by a border drawn by
  76. * <code>drawGroove()</code>
  77. *
  78. * @return the inset of a groove border
  79. */
  80. public static Insets getGrooveInsets() {
  81. return GROOVE_INSETS;
  82. }
  83. public static void drawBezel(Graphics g, int x, int y, int w, int h,
  84. boolean isPressed, boolean isDefault,
  85. Color shadow, Color darkShadow,
  86. Color highlight, Color lightHighlight)
  87. {
  88. Color oldColor = g.getColor(); // Make no net change to g
  89. g.translate(x, y);
  90. if (isPressed) {
  91. if (isDefault) {
  92. g.setColor(darkShadow); // outer border
  93. g.drawRect(0, 0, w-1, h-1);
  94. }
  95. g.setColor(shadow); // inner border
  96. g.drawRect(1, 1, w-3, h-3);
  97. }
  98. else {
  99. if (isDefault) {
  100. g.setColor(darkShadow);
  101. g.drawRect(0, 0, w-1, h-1);
  102. g.setColor(lightHighlight);
  103. g.drawLine(1, 1, 1, h-3);
  104. g.drawLine(2, 1, w-3, 1);
  105. g.setColor(highlight);
  106. g.drawLine(2, 2, 2, h-4);
  107. g.drawLine(3, 2, w-4, 2);
  108. g.setColor(shadow);
  109. g.drawLine(2, h-3, w-3, h-3);
  110. g.drawLine(w-3, 2, w-3, h-4);
  111. g.setColor(darkShadow);
  112. g.drawLine(1, h-2, w-2, h-2);
  113. g.drawLine(w-2, h-2, w-2, 1);
  114. }
  115. else {
  116. g.setColor(lightHighlight);
  117. g.drawLine(0, 0, 0, h-1);
  118. g.drawLine(1, 0, w-2, 0);
  119. g.setColor(highlight);
  120. g.drawLine(1, 1, 1, h-3);
  121. g.drawLine(2, 1, w-3, 1);
  122. g.setColor(shadow);
  123. g.drawLine(1, h-2, w-2, h-2);
  124. g.drawLine(w-2, 1, w-2, h-3);
  125. g.setColor(darkShadow);
  126. g.drawLine(0, h-1, w-1, h-1);
  127. g.drawLine(w-1, h-1, w-1, 0);
  128. }
  129. g.translate(-x, -y);
  130. g.setColor(oldColor);
  131. }
  132. }
  133. public static void drawLoweredBezel(Graphics g, int x, int y, int w, int h,
  134. Color shadow, Color darkShadow,
  135. Color highlight, Color lightHighlight) {
  136. g.setColor(darkShadow);
  137. g.drawLine(0, 0, 0, h-1);
  138. g.drawLine(1, 0, w-2, 0);
  139. g.setColor(shadow);
  140. g.drawLine(1, 1, 1, h-2);
  141. g.drawLine(1, 1, w-3, 1);
  142. g.setColor(lightHighlight);
  143. g.drawLine(0, h-1, w-1, h-1);
  144. g.drawLine(w-1, h-1, w-1, 0);
  145. g.setColor(highlight);
  146. g.drawLine(1, h-2, w-2, h-2);
  147. g.drawLine(w-2, h-2, w-2, 1);
  148. }
  149. /** Draw a string with the graphics g at location (x,y) just like g.drawString() would.
  150. * The first occurence of underlineChar in text will be underlined. The matching is
  151. * not case sensitive.
  152. */
  153. public static void drawString(Graphics g,String text,int underlinedChar,int x,int y) {
  154. // char b[] = new char[1];
  155. // String s;
  156. char lc,uc;
  157. int index=-1,lci,uci;
  158. if(underlinedChar != '\0') {
  159. // b[0] = (char)underlinedChar;
  160. // s = new String(b).toUpperCase();
  161. // uc = s.charAt(0);
  162. uc = Character.toUpperCase((char)underlinedChar);
  163. // s = new String(b).toLowerCase();
  164. lc = Character.toLowerCase((char)underlinedChar);
  165. uci = text.indexOf(uc);
  166. lci = text.indexOf(lc);
  167. if(uci == -1)
  168. index = lci;
  169. else if(lci == -1)
  170. index = uci;
  171. else
  172. index = (lci < uci) ? lci : uci;
  173. }
  174. g.drawString(text,x,y);
  175. if(index != -1) {
  176. FontMetrics fm = g.getFontMetrics();
  177. // Rectangle underlineRect = new Rectangle();
  178. int underlineRectX = x + fm.stringWidth(text.substring(0,index));
  179. int underlineRectY = y;
  180. int underlineRectWidth = fm.charWidth(text.charAt(index));
  181. int underlineRectHeight = 1;
  182. g.fillRect(underlineRectX, underlineRectY + fm.getDescent() - 1,
  183. underlineRectWidth, underlineRectHeight);
  184. }
  185. }
  186. public static void drawDashedRect(Graphics g,int x,int y,int width,int height) {
  187. int vx,vy;
  188. // draw upper and lower horizontal dashes
  189. for (vx = x; vx < (x + width); vx+=2) {
  190. g.drawLine(vx, y, vx, y);
  191. g.drawLine(vx, y + height-1, vx, y + height-1);
  192. }
  193. // draw left and right vertical dashes
  194. for (vy = y; vy < (y + height); vy+=2) {
  195. g.drawLine(x, vy, x, vy);
  196. g.drawLine(x+width-1, vy, x + width-1, vy);
  197. }
  198. }
  199. public static Dimension getPreferredButtonSize(AbstractButton b, int textIconGap)
  200. {
  201. if(b.getComponentCount() > 0) {
  202. return null;
  203. }
  204. Icon icon = (Icon) b.getIcon();
  205. String text = b.getText();
  206. Font font = b.getFont();
  207. FontMetrics fm = b.getToolkit().getFontMetrics(font);
  208. Rectangle iconR = new Rectangle();
  209. Rectangle textR = new Rectangle();
  210. Rectangle viewR = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
  211. SwingUtilities.layoutCompoundLabel(
  212. (JComponent) b, fm, text, icon,
  213. b.getVerticalAlignment(), b.getHorizontalAlignment(),
  214. b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  215. viewR, iconR, textR, (text == null ? 0 : textIconGap)
  216. );
  217. /* The preferred size of the button is the size of
  218. * the text and icon rectangles plus the buttons insets.
  219. */
  220. Rectangle r = iconR.union(textR);
  221. Insets insets = b.getInsets();
  222. r.width += insets.left + insets.right;
  223. r.height += insets.top + insets.bottom;
  224. /* Ensure that the width and height of the button is odd,
  225. * to allow for the focus line.
  226. */
  227. if(r.width % 2 == 0) { r.width += 1; }
  228. if(r.height % 2 == 0) { r.height += 1; }
  229. return r.getSize();
  230. }
  231. /*
  232. * Convenience function for determining ComponentOrientation. Helps us
  233. * avoid having Munge directives throughout the code.
  234. */
  235. static boolean isLeftToRight( Component c ) {
  236. return c.getComponentOrientation().isLeftToRight();
  237. }
  238. }