Hi, inspired by the email from theUserBL, I digged a little for myself and finally 'decoded' the gradient parameters in the UI defaults of JDK1.5 and implemented the gradient algorithm using only plain Graphics. (Of course, as soon as we have a working Graphics2D this can easily be enhanced with using Graphics2D).
This patch contains the actual painting methods. I'll build this into the Swing components now. 2005-11-15 Roman Kennke <[EMAIL PROTECTED]> * javax/swing/plaf/metal/MetalUtils.java (paintGradient): New utility method(s). (paintHorizontalGradient): New utility method. (paintVerticalGradient): New utility method. /Roman
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 [EMAIL PROTECTED] #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 + * <code>uiProp</code>. The value is expected to be a [EMAIL PROTECTED] List} that + * contains 4 values: two [EMAIL PROTECTED] Double}s and 3 [EMAIL PROTECTED] 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: + * <pre> + * + * +-------+--------+--------+-----------------------------+ + * | | | | | + * +-------+--------+--------+-----------------------------+ + * c1 -> c2 -- c2 -> c1 --------> c3 + * < -g1- > < -g2- > < -g1- > + * </pre> + * + * There are 4 distinct areas in this gradient: + * <ol> + * <li>A gradient from color 1 to color 2 with the relative width specified + * by <code>g1</code></li> + * <li>A solid area with the color 2 and the relative width specified by + * <code>g2</code></li> + * <li>A gradient from color 2 to color 1 with the relative width specified + * by <code>g1</code></li> + * + * @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 + * [EMAIL PROTECTED] SwingConstants#HORIZONTAL} or [EMAIL PROTECTED] 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 [EMAIL PROTECTED] #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 [EMAIL PROTECTED] #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); + } } }
_______________________________________________ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches