|
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());
}
}
|