alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 *
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
/*
 * DropShadowBorder.java
 *
 * Created on December 22, 2003, 9:06 PM
 */

package org.netbeans.swing.plaf.aqua;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.UIManager;
import javax.swing.border.Border;

/** A translucent drop shadow border class with settable colors and size.
 * Generally it's a goood idea to use a transparent color as the second
 * color.  The default size is 5 pixels, and the default colors are 
 * UIManager.getColor("controlDkShadow") for the
 * darker portion of the shadow, fading towards transparent white.
 *
 * @author  Tim Boudreau   */
public final class DropShadowBorder implements Border {
    int offset = 7;
    /** Scratch array for x coordinates to avoid extra allocations while painting */
    private static final int[] xpoints = new int[5];
    /** Scratch array for y coordinates to avoid extra allocations while painting */
    private static final int[] ypoints = new int[5];
    /** Default light shadow color if none is specified */
    static final Color DEFAULT_SHADOWLIGHT=new Color(255, 255, 255, 0);
    /** Field for the light shadow color */
    private Color shadowLight = DEFAULT_SHADOWLIGHT;
    /** Field for the dark shadow color */
    private Color shadowDark = null;
    /** AlphaComposite doesn't cache non 1.0 alpha instances, so we will */
    private static final Composite transparency =
        AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);
    
    /** Creates a new instance of DropShadowBorder with default settings */
    public DropShadowBorder() {
    }
    
    private Color getShadowLight() {
        return DEFAULT_SHADOWLIGHT;
    }
    
    private Color getShadowDark() {
        Color result = null;
        if (shadowDark == null) {
            result = UIManager.getColor("controlDkShadow"); //NOI18N
            result = new Color (result.getRed(), result.getGreen(), result.getBlue(), 128);
        } else {
            result = shadowDark;
        }
        return result;
    }
    private static final int WIDTH = 17;
    private static final int HEIGHT = 17;
    private static final int ARC = 12;
    public Insets getBorderInsets(Component c) {
        return new Insets(1,WIDTH,HEIGHT + 5, WIDTH);
    }
    
    public boolean isBorderOpaque() {
        return false;
    }
    
    private static final int GAP = ARC / 2;
    public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
        setupAntialiasing (g);
        
        Graphics2D g2d = (Graphics2D) g;
        Composite comp = g2d.getComposite();
        Paint paint = g2d.getPaint();
        try {
            Insets ins = getBorderInsets(c);
            
            int bottom = (y + (h - (ins.bottom + ins.top))) + GAP;
            int left = (x + ins.left) - GAP;
            int right = (x + w - ins.right) + GAP;
            int top = (y + ins.top);
            
            int arctop = y + (h - (ins.bottom + ins.top + ARC));
            int arcright = right - (ARC + GAP);
            int arcleft = x + ins.left + ARC;
            
            GeneralPath gp = new GeneralPath();
            gp.moveTo (left, top + 27); //orig: left, top - 
            
            gp.lineTo (left, arctop); 
            gp.quadTo (left, bottom, arcleft, bottom);
            
            gp.lineTo (arcright, bottom);
                        
            gp.quadTo (right, bottom, right, arctop);
            
            //**Special handling for Aqua tabs - move to near the top of the
            //right edge
            gp.lineTo (right, top + 27);
            //Do a slight curve in on the upper right side to the bottom
            //of the tabs are, inset a bit like the tabs are
            gp.quadTo (right, top + 22, right - 6, top + 18);
            //Up the right edge of the tab
            gp.lineTo (right - 6, top + 5);
            //Curve at the top of the tab
            gp.quadTo (right - 6, top, right - 14, top);
            //Across the top toward the left edge
            gp.lineTo (left + 11, top);
            //And do a curve there too
            gp.quadTo (left + 8, top, left + 8, top + 3);
            gp.lineTo (left + 8, top + 16);
            gp.quadTo (left, top + 21, left, top + 26);
            
            

/*            gp.quadTo (left, top, left + 9, top);
            gp.lineTo (left + 6, top + 16); //Fragile - connected with tab heights
            gp.lineTo (left + 6, top + 3);
 */
            
            gp.closePath();
            
            g.setColor (Color.WHITE);
            g2d.fill (gp);
            
            Area a = new Area (new Rectangle (x, y, w, h));
            a.subtract (new Area (gp));
            
            g2d.setPaint (new ShapeGradientPaint (gp.getBounds(), getShadowDark(), getShadowLight()));
            g2d.fill(a);
            
            g.setColor (UIManager.getColor ("controlShadow")); //NOI18N
            g2d.draw(gp);
            
            
        } finally {
            g2d.setComposite(comp);
            g2d.setPaint(paint);
        }
    }
    

    private static Map hintsMap = null;
    private static Map getHints() {
        if (hintsMap == null) {
            hintsMap = new HashMap();
            hintsMap.put(RenderingHints.KEY_FRACTIONALMETRICS,
                         RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            hintsMap.put(RenderingHints.KEY_TEXT_ANTIALIASING,
                         RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            hintsMap.put(RenderingHints.KEY_ANTIALIASING,
                         RenderingHints.VALUE_ANTIALIAS_ON);
        }
        return hintsMap;
    }

    public static final void setupAntialiasing(Graphics g) {
        ((Graphics2D) g).addRenderingHints(getHints());
    }    
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.