1. /*
  2. * @(#)MetalBumps.java 1.18 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.metal;
  8. import java.awt.*;
  9. import javax.swing.*;
  10. import java.io.*;
  11. import java.util.*;
  12. /**
  13. * Implements the bumps used throughout the Metal Look and Feel.
  14. *
  15. * @version 1.18 11/29/01
  16. * @author Tom Santos
  17. * @author Steve Wilson
  18. */
  19. class MetalBumps implements Icon {
  20. protected int xBumps;
  21. protected int yBumps;
  22. protected Color topColor = MetalLookAndFeel.getPrimaryControlHighlight();
  23. protected Color shadowColor = MetalLookAndFeel.getPrimaryControlDarkShadow();
  24. protected Color backColor = MetalLookAndFeel.getPrimaryControlShadow();
  25. protected static Vector buffers = new Vector();
  26. protected BumpBuffer buffer;
  27. public MetalBumps( Dimension bumpArea ) {
  28. this( bumpArea.width, bumpArea.height );
  29. }
  30. public MetalBumps( int width, int height ) {
  31. setBumpArea( width, height );
  32. buffer = getBuffer( topColor, shadowColor, backColor );
  33. if ( buffer == null ) {
  34. createBuffer();
  35. }
  36. }
  37. public MetalBumps( int width, int height,
  38. Color newTopColor, Color newShadowColor, Color newBackColor ) {
  39. setBumpArea( width, height );
  40. setBumpColors( newTopColor, newShadowColor, newBackColor );
  41. buffer = getBuffer( topColor, shadowColor, backColor );
  42. if ( buffer == null ) {
  43. createBuffer();
  44. }
  45. }
  46. protected void createBuffer() {
  47. buffer = new BumpBuffer( topColor, shadowColor, backColor );
  48. buffers.addElement( buffer );
  49. }
  50. protected BumpBuffer getBuffer( Color aTopColor, Color aShadowColor, Color aBackColor ) {
  51. BumpBuffer result = null;
  52. Enumeration elements = buffers.elements();
  53. while ( elements.hasMoreElements() ) {
  54. BumpBuffer aBuffer = (BumpBuffer)elements.nextElement();
  55. if ( aBuffer.hasSameColors( aTopColor, aShadowColor, aBackColor ) ) {
  56. result = aBuffer;
  57. break;
  58. }
  59. }
  60. return result;
  61. }
  62. public void setBumpArea( Dimension bumpArea ) {
  63. setBumpArea( bumpArea.width, bumpArea.height );
  64. }
  65. public void setBumpArea( int width, int height ) {
  66. xBumps = width / 2;
  67. yBumps = height / 2;
  68. }
  69. public void setBumpColors( Color newTopColor, Color newShadowColor, Color newBackColor ) {
  70. topColor = newTopColor;
  71. shadowColor = newShadowColor;
  72. backColor = newBackColor;
  73. buffer = getBuffer( topColor, shadowColor, backColor );
  74. if ( buffer == null ) {
  75. createBuffer();
  76. }
  77. }
  78. public void paintIcon( Component c, Graphics g, int x, int y ) {
  79. int bufferWidth = buffer.getImageSize().width;
  80. int bufferHeight = buffer.getImageSize().height;
  81. int iconWidth = getIconWidth();
  82. int iconHeight = getIconHeight();
  83. int x2 = x + iconWidth;
  84. int y2 = y + iconHeight;
  85. int savex = x;
  86. while (y < y2) {
  87. int h = Math.min(y2 - y, bufferHeight);
  88. for (x = savex; x < x2; x += bufferWidth) {
  89. int w = Math.min(x2 - x, bufferWidth);
  90. g.drawImage(buffer.getImage(),
  91. x, y, x+w, y+h,
  92. 0, 0, w, h,
  93. null);
  94. }
  95. y += bufferHeight;
  96. }
  97. }
  98. public int getIconWidth() {
  99. return xBumps * 2;
  100. }
  101. public int getIconHeight() {
  102. return yBumps * 2;
  103. }
  104. }
  105. class BumpBuffer {
  106. static Frame frame;
  107. static Component component;
  108. static final int IMAGE_SIZE = 64;
  109. static Dimension imageSize = new Dimension( IMAGE_SIZE, IMAGE_SIZE );
  110. transient Image image;
  111. Color topColor;
  112. Color shadowColor;
  113. Color backColor;
  114. public BumpBuffer( Color aTopColor, Color aShadowColor, Color aBackColor ) {
  115. createComponent();
  116. image = getComponent().createImage( IMAGE_SIZE, IMAGE_SIZE );
  117. topColor = aTopColor;
  118. shadowColor = aShadowColor;
  119. backColor = aBackColor;
  120. fillBumpBuffer();
  121. }
  122. public boolean hasSameColors( Color aTopColor, Color aShadowColor, Color aBackColor ) {
  123. return topColor.equals( aTopColor ) &&
  124. shadowColor.equals( aShadowColor ) &&
  125. backColor.equals( aBackColor );
  126. }
  127. public Image getImage() {
  128. if (image == null) {
  129. image = getComponent().createImage( IMAGE_SIZE, IMAGE_SIZE );
  130. fillBumpBuffer();
  131. }
  132. return image;
  133. }
  134. public Dimension getImageSize() {
  135. return imageSize;
  136. }
  137. protected void fillBumpBuffer() {
  138. Graphics g = image.getGraphics();
  139. g.setColor( backColor );
  140. g.fillRect( 0, 0, IMAGE_SIZE, IMAGE_SIZE );
  141. // PENDING- (STEVE) - remove old and slow, leave for comparison for now
  142. /*
  143. int columnX = 0;
  144. int xBumps = IMAGE_SIZE / 2;
  145. for ( int i = 0; i < xBumps; ++i, columnX += 2 ) {
  146. paintColumn( g, columnX, i % 2 == 0 ? 0 : 2 );
  147. }
  148. */
  149. g.setColor(topColor);
  150. for (int x = 0; x < IMAGE_SIZE; x+=4) {
  151. for (int y = 0; y < IMAGE_SIZE; y+=4) {
  152. g.drawLine( x, y, x, y );
  153. g.drawLine( x+2, y+2, x+2, y+2);
  154. }
  155. }
  156. g.setColor(shadowColor);
  157. for (int x = 0; x < IMAGE_SIZE; x+=4) {
  158. for (int y = 0; y < IMAGE_SIZE; y+=4) {
  159. g.drawLine( x+1, y+1, x+1, y+1 );
  160. g.drawLine( x+3, y+3, x+3, y+3);
  161. }
  162. }
  163. }
  164. // PENDING- (STEVE) - remove old and slow, leave for comparison for now
  165. /*
  166. protected void paintColumn( Graphics g, int x, int y ) {
  167. while ( y <= IMAGE_SIZE - 1 ) {
  168. g.setColor( topColor );
  169. g.drawLine( x, y, x, y );
  170. g.setColor( shadowColor );
  171. g.drawLine( x + 1, y + 1, x + 1, y + 1 );
  172. y += 4;
  173. }
  174. }
  175. */
  176. protected Component getComponent() {return component;}
  177. protected void createComponent() {
  178. if (frame == null) {
  179. frame = new Frame( "bufferCreator" );
  180. }
  181. if (component == null ) {
  182. component = new Canvas();
  183. frame.add( component, BorderLayout.CENTER );
  184. }
  185. // fix for 4185993 (moved this outside if block)
  186. frame.addNotify();
  187. }
  188. }