KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ButtonFilter


1 /*
2  * @(#)ButtonFilter.java 1.16 06/02/22
3  *
4  * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * -Redistribution of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * -Redistribution in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * Neither the name of Sun Microsystems, Inc. or the names of contributors may
17  * be used to endorse or promote products derived from this software without
18  * specific prior written permission.
19  *
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
22  * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
23  * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN")
24  * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
25  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
26  * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
27  * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
28  * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
29  * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  * You acknowledge that this software is not designed, licensed or intended
33  * for use in the design, construction, operation or maintenance of any
34  * nuclear facility.
35  */

36
37 /*
38  * @(#)ButtonFilter.java 1.16 06/02/22
39  */

40
41 import java.applet.Applet JavaDoc;
42 import java.awt.Image JavaDoc;
43 import java.awt.Graphics JavaDoc;
44 import java.awt.Rectangle JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.util.Vector JavaDoc;
47 import java.util.Hashtable JavaDoc;
48 import java.net.URL JavaDoc;
49 import java.awt.image.*;
50 import java.net.MalformedURLException JavaDoc;
51
52 /**
53  * An extensible ImageMap applet class.
54  * The active areas on the image are controlled by ImageArea classes
55  * that can be dynamically loaded over the net.
56  *
57  * @author Jim Graham
58  * @version 1.16, 02/22/06
59  */

60 class ButtonFilter extends RGBImageFilter {
61     boolean pressed;
62     int defpercent;
63     int border;
64     int width;
65     int height;
66
67     ColorModel models[] = new ColorModel[7];
68     ColorModel origbuttonmodel;
69
70     public ButtonFilter(boolean press, int p, int b, int w, int h) {
71     pressed = press;
72     defpercent = p;
73     border = b;
74     width = w;
75     height = h;
76     }
77
78     public void setHints(int hints) {
79     super.setHints(hints & (~ImageConsumer.COMPLETESCANLINES));
80     }
81
82     public void setColorModel(ColorModel model) {
83     if (model instanceof IndexColorModel && true) {
84         IndexColorModel icm = (IndexColorModel) model;
85         models[0] = filterIndexColorModel(icm, false, false, 0);
86         models[1] = filterIndexColorModel(icm, true, !pressed, defpercent);
87         models[2] = null;
88         if (pressed) {
89         models[3] = filterIndexColorModel(icm, true, false,
90                           defpercent/2);
91         } else {
92         models[3] = models[0];
93         }
94         models[4] = null;
95         models[5] = filterIndexColorModel(icm, true, pressed, defpercent);
96         models[6] = models[0];
97         origbuttonmodel = model;
98         consumer.setColorModel(models[3]);
99     } else {
100         super.setColorModel(model);
101     }
102     }
103
104     public IndexColorModel filterIndexColorModel(IndexColorModel icm,
105                          boolean opaque,
106                          boolean brighter,
107                          int percent) {
108     byte r[] = new byte[256];
109     byte g[] = new byte[256];
110     byte b[] = new byte[256];
111     byte a[] = new byte[256];
112     int mapsize = icm.getMapSize();
113     icm.getReds(r);
114     icm.getGreens(g);
115     icm.getBlues(b);
116     if (opaque) {
117         icm.getAlphas(a);
118         for (int i = 0; i < mapsize; i++) {
119         int rgb = filterRGB(icm.getRGB(i), brighter, percent);
120         a[i] = (byte) (rgb >> 24);
121         r[i] = (byte) (rgb >> 16);
122         g[i] = (byte) (rgb >> 8);
123         b[i] = (byte) (rgb >> 0);
124         }
125     }
126     return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, a);
127     }
128
129     /**
130      * Define the ranges of varying highlight for the button.
131      * ranges is an array of 8 values which split up a scanline into
132      * 7 different regions of highlighting effect:
133      *
134      * ranges[0-1] = area outside of left edge of button
135      * ranges[1-2] = area inside UpperLeft highlight region left of center
136      * ranges[2-3] = area requiring custom highlighting left of center
137      * ranges[3-4] = area inside center of button
138      * ranges[4-5] = area requiring custom highlighting right of center
139      * ranges[5-6] = area inside LowerRight highlight region right of center
140      * ranges[6-7] = area outside of right edge of button
141      * ranges[8-9] = y coordinates for which these ranges apply
142      *
143      * Note that ranges[0-1] and ranges[6-7] are empty where the edges of
144      * the button touch the left and right edges of the image (everywhere
145      * on a square button) and ranges[2-3] and ranges[4-5] are only nonempty
146      * in those regions where the UpperLeft highlighting has leaked over
147      * the "top" of the button onto parts of its right edge or where the
148      * LowerRight highlighting has leaked under the "bottom" of the button
149      * onto parts of its left edge (can't happen on square buttons, happens
150      * occasionally on round buttons).
151      */

152     public void buttonRanges(int y, int ranges[]) {
153     ranges[0] = ranges[1] = 0;
154     if (y < border) {
155         ranges[2] = ranges[3] = ranges[4] = ranges[5] = width - y;
156         ranges[8] = ranges[9] = y;
157     } else if (y > height - border) {
158         ranges[2] = ranges[3] = ranges[4] = ranges[5] = height - y;
159         ranges[8] = ranges[9] = y;
160     } else {
161         ranges[2] = ranges[3] = border;
162         ranges[4] = ranges[5] = width - border;
163         ranges[8] = border;
164         ranges[9] = height - border;
165     }
166     ranges[6] = ranges[7] = width;
167     }
168
169     private int savedranges[];
170
171     protected int[] getRanges(int y) {
172     int ranges[] = savedranges;
173     if (ranges == null) {
174         ranges = savedranges = new int[10];
175         ranges[8] = ranges[9] = -1;
176     }
177     if (y < ranges[8] || y > ranges[9]) {
178         buttonRanges(y, ranges);
179     }
180     return ranges;
181     }
182
183     public void setPixels(int x, int y, int w, int h,
184               ColorModel model, byte pixels[], int off,
185               int scansize) {
186     if (model == origbuttonmodel) {
187         int ranges[] = getRanges(y);
188         int x2 = x + w;
189         int y2 = y + h;
190         for (int cy = y; cy < y2; cy++) {
191         if (cy < ranges[8] || cy > ranges[9]) {
192             buttonRanges(cy, ranges);
193         }
194         for (int i = 0; i < 7; i++) {
195             if (x2 > ranges[i] && x < ranges[i+1]) {
196             int cx1 = Math.max(x, ranges[i]);
197             int cx2 = Math.min(x2, ranges[i+1]);
198             if (models[i] == null) {
199                 super.setPixels(cx1, cy, cx2 - cx1, 1,
200                         model, pixels,
201                         off + (cx1 - x), scansize);
202             } else {
203                 if (cx1 < cx2) {
204                 consumer.setPixels(cx1, cy, cx2 - cx1, 1,
205                            models[i], pixels,
206                            off + (cx1 - x), scansize);
207                 }
208             }
209             }
210         }
211         off += scansize;
212         }
213     } else {
214         super.setPixels(x, y, w, h, model, pixels, off, scansize);
215     }
216     }
217
218     public int filterRGB(int x, int y, int rgb) {
219     boolean brighter;
220     int percent;
221     if ((x < border && y < height - x) || (y < border && x < width - y)) {
222         brighter = !pressed;
223         percent = defpercent;
224     } else if (x >= width - border || y >= height - border) {
225         brighter = pressed;
226         percent = defpercent;
227     } else if (pressed) {
228         brighter = false;
229         percent = defpercent / 2;
230     } else {
231         return rgb & 0x00ffffff;
232     }
233     return filterRGB(rgb, brighter, percent);
234     }
235
236     public int filterRGB(int rgb, boolean brighter, int percent) {
237     int r = (rgb >> 16) & 0xff;
238     int g = (rgb >> 8) & 0xff;
239     int b = (rgb >> 0) & 0xff;
240     if (brighter) {
241         r = (255 - ((255 - r) * (100 - percent) / 100));
242         g = (255 - ((255 - g) * (100 - percent) / 100));
243         b = (255 - ((255 - b) * (100 - percent) / 100));
244     } else {
245         r = (r * (100 - percent) / 100);
246         g = (g * (100 - percent) / 100);
247         b = (b * (100 - percent) / 100);
248     }
249     return (rgb & 0xff000000) | (r << 16) | (g << 8) | (b << 0);
250     }
251
252   public String JavaDoc getAppletInfo() {
253     return "Title: ButtonFilter \nAuthor: Jim Graham \nAn extensible ImageMap applet class. The active areas on the image are controlled by ImageArea classes that can be dynamically loaded over the net.";
254   }
255 }
256
Popular Tags