KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > tabcontrol > plaf > ChicletWrapper


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  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.swing.tabcontrol.plaf;
20
21 import javax.swing.*;
22 import java.awt.*;
23 import java.awt.geom.AffineTransform JavaDoc;
24 import java.awt.image.BufferedImage JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Date JavaDoc;
28
29 /**
30  * GenericGlowingChiclet works nicely to draw Aqua-style decorations, but is a bit
31  * slow. In particular, Area.pruneEdges() is not cheap, but is heavily used to divide
32  * the geometry.
33  *
34  * This wrapper class provides a cache of bitmaps painted by GenericGlowingChiclet,
35  * timestamped against the last
36  * time they were used, and occasionally prunes not recently used bitmaps.
37  *
38  * @author Tim Boudreau
39  */

40 public class ChicletWrapper implements Runnable JavaDoc {
41     private boolean allowVertical = true;
42     private boolean leftNotch = false;
43     private boolean rightNotch = false;
44     private int state = 0;
45     private Rectangle bounds = new Rectangle();
46     private float[] arcs = new float[4];
47     GenericGlowingChiclet chiclet = GenericGlowingChiclet.INSTANCE; //XXX kill static instance
48

49     public void setState (int state) {
50         this.state = state;
51     }
52
53     public void setBounds (int x, int y, int w, int h) {
54         bounds.setBounds (x, y, w, h);
55     }
56
57     static int drawCount = 0;
58     public void draw (Graphics g) {
59         if (bounds.width == 0 || bounds.height == 0) {
60             return;
61         }
62         BufferedImage JavaDoc img = findBufferedImage();
63         ((Graphics2D) g).drawRenderedImage(img, AffineTransform.getTranslateInstance(0, 0));
64         drawCount ++;
65         if (drawCount % 100 == 0) {
66             //Occasionally prune old bitmaps
67
SwingUtilities.invokeLater(this);
68         }
69     }
70
71     public void setArcs (float a, float b, float c, float d) {
72         arcs[0] = a;
73         arcs[1] = b;
74         arcs[2] = c;
75         arcs[3] = d;
76     }
77
78
79     public void setAllowVertical (boolean b) {
80         allowVertical = b;
81     }
82
83     public void setNotch (boolean right, boolean left) {
84         leftNotch = left;
85         rightNotch = right;
86     }
87
88     public Long JavaDoc hash() {
89         long result =
90             state * 701
91             + Double.doubleToLongBits(arcs[0]) * 31
92             + Double.doubleToLongBits(arcs[1]) * 37
93             + Double.doubleToLongBits(arcs[2]) * 43
94             + Double.doubleToLongBits(arcs[3]) * 47
95             + bounds.width * 6703
96             + bounds.height * 1783;
97
98         if (leftNotch) {
99             result *= 3121;
100         }
101         if (rightNotch) {
102             result *= 4817;
103         }
104         if (allowVertical) {
105             result *= 1951;
106         }
107
108         return new Long JavaDoc(result);
109     }
110
111     private static HashMap JavaDoc<CacheEntry,BufferedImage JavaDoc> cache = new HashMap JavaDoc<CacheEntry,BufferedImage JavaDoc>();
112
113     private BufferedImage JavaDoc findBufferedImage() {
114         Long JavaDoc hash = hash();
115         CacheEntry entry = new CacheEntry (hash);
116
117         BufferedImage JavaDoc result = cache.get(entry);
118         if (result == null) {
119             result = createImage();
120         }
121         //Store our new entry with new timestamp, even if we found an old one
122
cache.put (entry, result);
123         return result;
124     }
125
126     private BufferedImage JavaDoc createImage() {
127         BufferedImage JavaDoc img = new BufferedImage JavaDoc (bounds.width, bounds.height,
128             BufferedImage.TYPE_INT_ARGB_PRE);
129         chiclet.setNotch(rightNotch, leftNotch);
130         chiclet.setArcs (arcs[0], arcs[1], arcs[2], arcs[3]);
131         chiclet.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
132         chiclet.setAllowVertical(allowVertical);
133         chiclet.setState (state);
134         Graphics g = img.getGraphics();
135         g.translate (-bounds.x, -bounds.y);
136         ColorUtil.setupAntialiasing(g);
137         chiclet.draw((Graphics2D)g);
138         g.translate (bounds.x, bounds.y);
139         return img;
140     }
141
142     public void run() {
143         if (cache.size() < 5) {
144             return;
145         }
146         HashMap JavaDoc<CacheEntry,BufferedImage JavaDoc> newCache = new HashMap JavaDoc<CacheEntry,BufferedImage JavaDoc>( cache );
147         long startTime = System.currentTimeMillis();
148         CacheEntry[] entries = (CacheEntry[]) newCache.keySet().toArray(new CacheEntry[0]);
149         Arrays.sort (entries);
150         for (int i=entries.length-1; i >= entries.length / 3; i--) {
151             if (startTime - entries[i].timestamp > 240000) {
152                 newCache.remove (entries[i]);
153             }
154         }
155         cache = newCache;
156     }
157
158     private static final class CacheEntry implements Comparable JavaDoc {
159         private final Long JavaDoc hash;
160         long timestamp = System.currentTimeMillis();
161         public CacheEntry (Long JavaDoc hash) {
162             this.hash = hash;
163         }
164
165         public boolean equals (Object JavaDoc o) {
166             if (o instanceof CacheEntry) {
167                 CacheEntry other = (CacheEntry) o;
168                 return other.hash() == hash();
169             } else if (o instanceof Long JavaDoc) {
170                 return ((Long JavaDoc) o).longValue() == hash();
171             } else {
172                 return false;
173             }
174         }
175
176         long hash() {
177             return hash.longValue();
178         }
179
180         public int hashCode() {
181             return hash.intValue();
182         }
183
184         public int compareTo(Object JavaDoc o) {
185             CacheEntry other = (CacheEntry) o;
186             //Okay, every 4 days we might let an unused bitmap get old
187
return (int) (timestamp - other.timestamp);
188         }
189
190         public String JavaDoc toString() {
191             return "CacheEntry: " + new Date JavaDoc(timestamp) + " hash " + hash();
192         }
193
194     }
195
196 }
197
Popular Tags