Index: javax/swing/plaf/metal/MetalUtils.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalUtils.java,v retrieving revision 1.6 diff -u -r1.6 MetalUtils.java --- javax/swing/plaf/metal/MetalUtils.java 15 Nov 2005 14:05:30 -0000 1.6 +++ javax/swing/plaf/metal/MetalUtils.java 16 Nov 2005 14:35:07 -0000 @@ -44,6 +44,10 @@ import java.awt.TexturePaint; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.util.List; + +import javax.swing.SwingConstants; +import javax.swing.UIManager; /** * Some utility and helper methods for the Metal Look & Feel. @@ -150,5 +154,253 @@ g.fillRect(1, 1, 1, 1); g.fillRect(3, 3, 1, 1); g.dispose(); + } + + /** + * Paints the typical Metal gradient. See address@hidden #paintGradient(Graphics, + * int, int, int, int, double, double, Color, Color, Color, int)} + * for more details. + * + * The parameters are fetched from the UIManager using the key + * uiProp. The value is expected to be a address@hidden List} that + * contains 4 values: two address@hidden Double}s and 3 address@hidden Color} object that + * together make up the parameters passed to the painting method. + * + * @param g the graphics context to use + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param dir the direction of the gradient, either + * @param uiProp the key of the UIManager property that has the parameters + */ + static void paintGradient(Graphics g, int x, int y, int w, int h, + int dir, String uiProp) + { + List params = (List) UIManager.get(uiProp); + double g1 = ((Double) params.get(0)).doubleValue(); + double g2 = ((Double) params.get(1)).doubleValue(); + Color c1 = (Color) params.get(2); + Color c2 = (Color) params.get(3); + Color c3 = (Color) params.get(4); + paintGradient(g, x, y, w, h, g1, g2, c1, c2, c3, dir); + } + + /** + * Paints the typical Metal gradient. The gradient is painted as follows: + *
+   * 
+   * +-------+--------+--------+-----------------------------+
+   * |       |        |        |                             |
+   * +-------+--------+--------+-----------------------------+
+   * c1  ->  c2  --   c2  ->   c1         -------->          c3
+   * < -g1- > < -g2- > < -g1- >
+   * 
+ * + * There are 4 distinct areas in this gradient: + *
    + *
  1. A gradient from color 1 to color 2 with the relative width specified + * by g1
  2. + *
  3. A solid area with the color 2 and the relative width specified by + * g2
  4. + *
  5. A gradient from color 2 to color 1 with the relative width specified + * by g1
  6. + * + * @param g the graphics context to use + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param g1 the relative width of the c1->c2 gradients + * @param g2 the relative width of the c2 solid area + * @param c1 the color 1 + * @param c2 the color 2 + * @param c3 the color 3 + * @param dir the direction of the gradient, either + * address@hidden SwingConstants#HORIZONTAL} or address@hidden SwingConstants#VERTICAL} + */ + static void paintGradient(Graphics g, int x, int y, int w, int h, double g1, + double g2, Color c1, Color c2, Color c3, int dir) + { + if (dir == SwingConstants.HORIZONTAL) + paintHorizontalGradient(g, x, y, w, h, g1, g2, c1, c2, c3); + else + paintVerticalGradient(g, x, y, w, h, g1, g2, c1, c2, c3); + } + + /** + * Paints a horizontal gradient. See address@hidden #paintGradient(Graphics, int, + * int, int, int, double, double, Color, Color, Color, int)} for details. + * + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param g1 the relative width of the c1->c2 gradients + * @param g2 the relative width of the c2 solid area + * @param c1 the color 1 + * @param c2 the color 2 + * @param c3 the color 3 + */ + static void paintHorizontalGradient(Graphics g, int x, int y, int w, int h, + double g1, double g2, Color c1, Color c2, + Color c3) + { + // Calculate the coordinates. + // The size of the first gradient area (c1->2). + int w1 = (int) (w * g1); + // The size of the solid c2 area. + int w2 = (int) (w * g2); + int x0 = x; + int x1 = x0 + w1; + int x2 = x1 + w2; + int x3 = x2 + w1; + int x4 = x + w; + + // Paint first gradient area (c1->c2). + int xc; // The current y coordinate. + for (xc = x0; xc < x1; xc++) + { + if (xc > x + w) + break; + + // Perform color interpolation; + double factor = (xc - x0) / (double) w1; + int rInt = (int) ((c2.getRed() - c1.getRed()) * factor + c1.getRed()); + int gInt = (int) ((c2.getGreen() - c1.getGreen()) * factor + + c1.getGreen()); + int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor + + c1.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(xc, y, xc, y + h); + } + // Paint solid c2 area. + g.setColor(c2); + g.fillRect(x1, y, x2 - x1, h); + + // Paint second gradient area (c2->c1). + for (xc = x2; xc < x3; xc++) + { + if (xc > x + w) + break; + + // Perform color interpolation; + double factor = (xc - x2) / (double) w1; + int rInt = (int) ((c1.getRed() - c2.getRed()) * factor + c2.getRed()); + int gInt = (int) ((c1.getGreen() - c2.getGreen()) * factor + + c2.getGreen()); + int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor + + c2.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(xc, y, xc, y + h); + } + + // Paint third gradient area (c1->c3). + for (xc = x3; xc < x4; xc++) + { + if (xc > x + w) + break; + + // Perform color interpolation; + double factor = (xc - x3) / (double) (x4 - x3); + int rInt = (int) ((c3.getRed() - c1.getRed()) * factor + c1.getRed()); + int gInt = (int) ((c3.getGreen() - c1.getGreen()) * factor + + c1.getGreen()); + int bInt = (int) ((c3.getBlue() - c1.getBlue()) * factor + + c1.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(xc, y, xc, y + h); + } + } + + /** + * Paints a vertical gradient. See address@hidden #paintGradient(Graphics, int, int, + * int, int, double, double, Color, Color, Color, int)} for details. + * + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @param g1 the relative width of the c1->c2 gradients + * @param g2 the relative width of the c2 solid area + * @param c1 the color 1 + * @param c2 the color 2 + * @param c3 the color 3 + */ + static void paintVerticalGradient(Graphics g, int x, int y, int w, int h, + double g1, double g2, Color c1, Color c2, + Color c3) + { + // Calculate the coordinates. + // The size of the first gradient area (c1->2). + int w1 = (int) (h * g1); + // The size of the solid c2 area. + int w2 = (int) (h * g2); + int y0 = y; + int y1 = y0 + w1; + int y2 = y1 + w2; + int y3 = y2 + w1; + int y4 = y + h; + + // Paint first gradient area (c1->c2). + int yc; // The current y coordinate. + for (yc = y0; yc < y1; yc++) + { + if (yc > y + h) + break; + + // Perform color interpolation; + double factor = (yc - y0) / (double) w1; + int rInt = (int) ((c2.getRed() - c1.getRed()) * factor + c1.getRed()); + int gInt = (int) ((c2.getGreen() - c1.getGreen()) * factor + + c1.getGreen()); + int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor + + c1.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(x, yc, x + w, yc); + } + // Paint solid c2 area. + g.setColor(c2); + g.fillRect(x, y1, w, y2 - y1); + + // Paint second gradient area (c2->c1). + for (yc = y2; yc < y3; yc++) + { + if (yc > y + h) + break; + + // Perform color interpolation; + double factor = (yc - y2) / (double) w1; + int rInt = (int) ((c1.getRed() - c2.getRed()) * factor + c2.getRed()); + int gInt = (int) ((c1.getGreen() - c2.getGreen()) * factor + + c2.getGreen()); + int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor + + c2.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(x, yc, x + w, yc); + } + + // Paint third gradient area (c1->c3). + for (yc = y3; yc < y4; yc++) + { + if (yc > y + h) + break; + + // Perform color interpolation; + double factor = (yc - y3) / (double) (y4 - y3); + int rInt = (int) ((c3.getRed() - c1.getRed()) * factor + c1.getRed()); + int gInt = (int) ((c3.getGreen() - c1.getGreen()) * factor + + c1.getGreen()); + int bInt = (int) ((c3.getBlue() - c1.getBlue()) * factor + + c1.getBlue()); + Color interpolated = new Color(rInt, gInt, bInt); + g.setColor(interpolated); + g.drawLine(x, yc, x + w, yc); + } } }