Gradient fill with left top light direction. - Java 2D Graphics

Java examples for 2D Graphics:Paint

Description

Gradient fill with left top light direction.

Demo Code


//package com.java2s;

import java.awt.*;

import java.util.HashMap;
import java.util.Map;

public class Main {
    private static Map<Integer, GradientPaint> gpCache = null;
    private static final boolean noGpCache = Boolean
            .getBoolean("netbeans.winsys.nogpcache");
    /**//  w w  w  .  j av a 2 s . co  m
     * constants for gradient borders
     */
    public static final int XP_BORDER_RIGHT = 1;
    public static final int XP_BORDER_BOTTOM = 2;

    /**
     * Gradient fill with left top light direction.
     */
    public static void xpFillRectGradient(Graphics2D g, Rectangle rect,
            Color brightC, Color darkC) {
        xpFillRectGradient(g, rect.x, rect.y, rect.width, rect.height,
                brightC, darkC, XP_BORDER_BOTTOM | XP_BORDER_RIGHT);
    }

    /**
     * Fills given rectangle in gradient style from bright to dark colors, with
     * virtual light shining from left top direction.
     */
    public static void xpFillRectGradient(Graphics2D g, int x, int y,
            int width, int height, Color brightC, Color darkC) {
        xpFillRectGradient(g, x, y, width, height, brightC, darkC,
                XP_BORDER_BOTTOM | XP_BORDER_RIGHT);
    }

    /**
     * Fills given rectangle in gradient style from bright to dark colors, with
     * optional emphasized borders.
     */
    public static void xpFillRectGradient(Graphics2D g, int x, int y,
            int width, int height, Color brightC, Color darkC,
            int borderType) {
        paintXpGradientBorder(g, x, y, width, height, darkC, borderType);
        int gradWidth = ((borderType & XP_BORDER_RIGHT) != 0) ? width - 2
                : width;
        int gradHeight = ((borderType & XP_BORDER_BOTTOM) != 0) ? height - 2
                : height;
        paintXpGradientFill(g, x, y, gradWidth, gradHeight, brightC, darkC);
    }

    /**
     * Paints border of given rectangle, which enhances "light shining" effect
     */
    private static void paintXpGradientBorder(Graphics g, int x, int y,
            int width, int height, Color darkC, int borderType) {
        // right and bottom border, darker
        if ((borderType & XP_BORDER_RIGHT) != 0) {
            Color color = adjustColor(darkC, -6, -5, -3);
            g.setColor(color);
            g.drawLine(x + width - 2, y, x + width - 2, y + height - 2);
            color = adjustColor(darkC, -27, -26, -20);
            g.setColor(color);
            g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
        }
        if ((borderType & XP_BORDER_BOTTOM) != 0) {
            Color color = adjustColor(darkC, -6, -5, -3);
            g.setColor(color);
            g.drawLine(x, y + height - 2, x + width - 2, y + height - 2);
            color = adjustColor(darkC, -27, -26, -20);
            g.setColor(color);
            g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
        }
    }

    /**
     * Fills given rectangle using top-down gradient fill of specified colors
     */
    private static void paintXpGradientFill(Graphics2D g, int x, int y,
            int width, int height, Color brightC, Color darkC) {
        GradientPaint gradient = getGradientPaint(x, y, brightC, x, y
                + height, darkC);
        g.setPaint(gradient);
        g.fillRect(x, y, width, height);
    }

    /**
     * Adjusts color by given values, positive values means brightening,
     * negative values darkening of original color.
     *
     * @return adjusted color
     */
    public static Color adjustColor(Color c, int rDiff, int gDiff, int bDiff) {
        if (c == null) {
            c = Color.GRAY;
        }
        int red = Math.max(0, Math.min(255, c.getRed() + rDiff));
        int green = Math.max(0, Math.min(255, c.getGreen() + gDiff));
        int blue = Math.max(0, Math.min(255, c.getBlue() + bDiff));
        return new Color(red, green, blue);
    }

    public static GradientPaint getGradientPaint(float x1, float y1,
            Color upper, float x2, float y2, Color lower) {
        return getGradientPaint(x1, y1, upper, x2, y2, lower, false);
    }

    /**
     * GradientPaint creation is somewhat expensive.  This method keeps cached
     * GradientPaint instances, and normalizes the resulting GradientPaint for
     * horizontal and vertical cases.  Note that this depends entirely on the
     * hashing algorithm for accuracy - there are hypothetical situations 
     * where the return value could be wrong, though none have as yet been 
     * encountered, and given that the number of gradient heights and widths
     * actually used in any UI are very small, such a situation is highly 
     * unlikely.
     */
    public static GradientPaint getGradientPaint(float x1, float y1,
            Color upper, float x2, float y2, Color lower, boolean repeats) {
        if (noGpCache) {
            return new GradientPaint(x1, y1, upper, x2, y2, lower, repeats);
        }

        //Only for test runs with disabled customizations
        if (upper == null) {
            upper = Color.BLUE;
        }

        if (lower == null) {
            lower = Color.ORANGE;
        }

        if (gpCache == null) {
            gpCache = new HashMap<Integer, GradientPaint>(20);
        }
        //Normalize any non-repeating gradients
        boolean horizontal = x1 == x2;
        boolean vertical = y1 == y2;
        if (horizontal && vertical) {
            //Hack: gradient paint w/ 2 matching points causes endless loop 
            //in native code on mac os, so pick a random number to make sure
            //that can't happen
            y1 = x1 + 28;
        } else if (horizontal && !repeats) {
            x1 = 0;
            x2 = 0;
        } else if (vertical && !repeats) {
            y1 = 0;
            y2 = 0;
        }
        //TODO: Normalize non-planar repeating gp's by vector/relative location

        //Generate a hash code for looking up an existing paint
        long bits = Double.doubleToLongBits(x1)
                + Double.doubleToLongBits(y1) * 37
                + Double.doubleToLongBits(x2) * 43
                + Double.doubleToLongBits(y2) * 47;
        int hash = ((((int) bits) ^ ((int) (bits >> 32)))
                ^ upper.hashCode() ^ (lower.hashCode() * 17))
                * (repeats ? 31 : 1);

        Integer key = new Integer(hash);
        GradientPaint result = gpCache.get(key);
        if (result == null) {
            result = new GradientPaint(x1, y1, upper, x2, y2, lower,
                    repeats);
            if (gpCache.size() > 40) {
                gpCache.clear();
            }
            gpCache.put(key, result);
        }
        return result;
    }
}

Related Tutorials