KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > plaf > aqua > FakeDropShadowBorder


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]" */

14 package org.netbeans.swing.plaf.aqua;
15
16 import java.awt.Color JavaDoc;
17 import java.awt.Component JavaDoc;
18 import java.awt.Graphics JavaDoc;
19 import java.awt.Graphics2D JavaDoc;
20 import java.awt.Insets JavaDoc;
21 import java.awt.Shape JavaDoc;
22 import java.awt.geom.AffineTransform JavaDoc;
23 import java.awt.geom.GeneralPath JavaDoc;
24 import java.awt.image.BufferedImage JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Map JavaDoc;
27 import javax.imageio.ImageIO JavaDoc;
28 import javax.swing.border.Border JavaDoc;
29
30 /**
31  * Replacement for original DropShadowBorder - uses a set of backing bitmaps
32  * to draw shadows instead of allocating a huge raster.
33  *
34  * @author Tim Boudreau
35  */

36 public class FakeDropShadowBorder implements Border JavaDoc {
37     
38     public FakeDropShadowBorder() {
39     }
40     
41     private static final int WIDTH = 17;
42     private static final int HEIGHT = 17;
43     public static final int ARC = 12;
44     public Insets JavaDoc getBorderInsets(Component JavaDoc c) {
45         return new Insets JavaDoc(1, 13, 25, 13);
46     }
47
48     /**
49      * Fill the area we are *not* going to paint with the translucent shadow,
50      * so the windows behind the popup window do not show through the gaps
51      * between the rectangle of the image and the shaped, rounded perimeter
52      * where the shadow is drawn.
53      */

54     public void fillBackground (Component JavaDoc c, Graphics2D JavaDoc gg,int x, int y, int w, int h) {
55         Shape JavaDoc clip = gg.getClip();
56         gg.setColor (Color.WHITE);
57         Insets JavaDoc ins = getBorderInsets(c);
58         //y offset for the bottom of the window
59
int bottom = h - ins.bottom + 6; //517
60
//y offset for the end of the curves around the bottom, from which
61
//the edges ascend
62
int bottomOffCurve = bottom - 20; //497
63
//The top of the inner part of the border
64
int top = ins.top + 3; //34
65
//The left edge
66
int left = ins.left - 2; //41
67
//The level of the "shoulders" in the border shape
68
int shoulderTop = top + 16; //50
69
//The y coordinate at which the edge segment stops and the shoulder
70
//curve stops
71
int shoulderTopOffCurve = shoulderTop + 9; //59
72
//the x position it which the top right curve begins to curl around
73
//the right corner
74
int rightOffCurve = x + w - 34; //329
75
//the right edge of the perimeter
76
int right = rightOffCurve + 24; //352
77

78         //Calculate a shape to fill, which matches the perceived perimeter of
79
//the border (larger than the actual component displayed to make room
80
//for our rounded borders
81
GeneralPath JavaDoc gp = new GeneralPath JavaDoc();
82         //start at the bottom after the left edge curve - first segment is a line
83
//upward - the left edge
84
gp.moveTo (left, bottomOffCurve);
85         gp.lineTo (left, shoulderTopOffCurve);
86         //relatively flat bezier curve making the left shoulder of the window border
87
gp.curveTo (left, shoulderTop, left + 6, shoulderTop, left + 8, shoulderTop + 1);
88         //and steeper, up and around to the top edge
89
gp.curveTo (left + 11, top, left + 19, top + 1, left + 25, top);
90         //top edge
91
gp.lineTo (rightOffCurve, top);
92         //steep curve back down to the right shoulder
93
gp.curveTo (rightOffCurve + 6, top, rightOffCurve + 17, top + 5, rightOffCurve + 16, shoulderTop);
94         //shallower curve out to the right to make the left shoulder
95
gp.curveTo (right - 4, shoulderTop + 1, right, shoulderTop, right, shoulderTop + 9);
96         //the right edge of the window border
97
gp.lineTo (right, bottomOffCurve);
98         //curve around to the left to the bottom edge
99
gp.curveTo (right + 1, bottom, right - 1, bottom + 1, right - 12, bottom);
100         //the bottom edge
101
gp.lineTo (left + 14, bottom);
102         //curve to the left and up to come back to where we started
103
gp.curveTo (left + 1, bottom, left - 1, bottom, left, bottomOffCurve);
104         gp.closePath();
105         //fill this with white; the window will overpaint it; this fills in so
106
//we don't see the windows underneath it peeking between the rounded
107
//border's edges and the smaller rectangle of the component inside it
108
gg.fill(gp);
109     }
110     
111     public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
112         Graphics2D JavaDoc gg = (Graphics2D JavaDoc) g;
113         //Fill in the space between the component rect and the border
114
//perimeter
115
fillBackground (c, gg, x, y, w, h);
116         //Tile the shadow pngs around the shape
117
BufferedImage JavaDoc b = getImage(upLeft);
118         int yoff = b.getHeight();
119         int topL = b.getWidth();
120         draw(gg, b, x, y);
121         
122         b = getImage(downRight);
123         draw(gg, b, x + w - b.getWidth(), y + h - b.getHeight());
124         int woff = b.getWidth();
125         
126         b = getImage(upRight);
127         draw(gg, b, x + w - b.getWidth(), y);
128         int topR = b.getWidth();
129         
130         b = getImage(downLeft);
131         int hoff = b.getHeight();
132         int xoff = b.getWidth();
133         draw(gg, b, x, y + h - b.getHeight());
134         
135         b = getImage (leftEdge);
136         tileVertical (x, y, yoff, hoff, h, b, gg);
137         
138         b = getImage (rightEdge);
139         tileVertical (x + w - (b.getWidth()), y, yoff, hoff, h, b, gg);
140         
141         b = getImage (bottom);
142         tileHorizontal(x, y + h - (b.getHeight() + 0), xoff, woff, w, b, gg);
143         
144         b = getImage (top);
145         tileHorizontal(x, y, xoff, woff, w, b, gg);
146         
147     }
148     
149     private final Color JavaDoc xpar = new Color JavaDoc (255, 255, 255, 0);
150     private void draw(Graphics2D JavaDoc g, BufferedImage JavaDoc b, int x, int y) {
151         g.setColor (xpar);
152         g.fillRect (x, y, b.getWidth(), b.getHeight());
153         g.drawRenderedImage(b, AffineTransform.getTranslateInstance(x,y));
154     }
155     
156     private void tileVertical (int x, int y, int yoff, int hoff, int h, BufferedImage JavaDoc img, Graphics2D JavaDoc g) {
157         h -= (hoff + yoff);
158         int times = h / img.getHeight();
159         int rem = h % img.getHeight();
160         y = y + yoff;
161         
162         for (int i=0; i < times; i++) {
163             g.drawRenderedImage (img, AffineTransform.getTranslateInstance(x, y));
164             y += img.getHeight();
165         }
166         if (rem > 0) {
167             img = img.getSubimage(0, 0, img.getWidth(), rem);
168             g.drawRenderedImage(img, AffineTransform.getTranslateInstance(x,y));
169         }
170     }
171     
172     private void tileHorizontal (int x, int y, int xoff, int woff, int w, BufferedImage JavaDoc img, Graphics2D JavaDoc g) {
173         w -= (woff + xoff);
174         int times = w / img.getWidth();
175         int rem = w % img.getWidth();
176         x += xoff;
177         
178         for (int i=0; i < times; i++) {
179             draw (g, img, x, y);
180             x += img.getWidth();
181         }
182         if (rem > 0) {
183             img = img.getSubimage(0, 0, rem, img.getHeight());
184             draw (g, img, x, y);
185         }
186     }
187     
188     
189     public boolean isBorderOpaque() {
190         return false;
191     }
192     
193     private static final String JavaDoc upLeft = "upLeft.png"; //NOI18N
194
private static final String JavaDoc downRight = "downRight.png"; //NOI18N
195
private static final String JavaDoc downLeft = "upRight.png"; //NOI18N
196
private static final String JavaDoc upRight = "downLeft.png"; //NOI18N
197
private static final String JavaDoc bottom = "bottom.png"; //NOI18N
198
private static final String JavaDoc leftEdge = "leftEdge.png"; //NOI18N
199
private static final String JavaDoc rightEdge = "rightEdge.png"; //NOI18N
200
private static final String JavaDoc top = "top.png";
201     
202     //Only one instance in VM, so perfectly safe to use instance cache - won't
203
//be populated unless used
204
private static Map JavaDoc<String JavaDoc, BufferedImage JavaDoc> imgs = new HashMap JavaDoc<String JavaDoc, BufferedImage JavaDoc>();
205     private static BufferedImage JavaDoc getImage(String JavaDoc s) {
206         BufferedImage JavaDoc result = imgs.get(s);
207         if (result == null) {
208             Exception JavaDoc e1 = null;
209             try {
210                 result = ImageIO.read(
211                         FakeDropShadowBorder.class.getResourceAsStream(s));
212             } catch (Exception JavaDoc e) {
213                 result = new BufferedImage JavaDoc (1, 1, BufferedImage.TYPE_INT_ARGB);
214                 e1 = e;
215             }
216             imgs.put (s, result);
217             if (e1 != null) {
218                 throw new IllegalStateException JavaDoc (e1);
219             }
220         }
221         return result;
222     }
223 }
224
Popular Tags