001: /*
002: * Copyright (c) 2001-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.looks.common;
032:
033: import java.awt.Image;
034: import java.awt.image.*;
035:
036: import javax.swing.GrayFilter;
037: import javax.swing.Icon;
038: import javax.swing.ImageIcon;
039: import javax.swing.JComponent;
040:
041: import com.jgoodies.looks.Options;
042:
043: /**
044: * An image filter that turns an icon into a grayscale icon. Used by
045: * the JGoodies Windows and Plastic L&Fs to create a disabled icon.<p>
046: *
047: * The high-resolution gray filter can be disabled globally using
048: * {@link Options#setHiResGrayFilterEnabled(boolean)}; it is enabled by default.
049: * The global setting can be overridden per component by setting
050: * the client property key {@link Options#HI_RES_DISABLED_ICON_CLIENT_KEY}
051: * to <code>Boolean.FALSE</code>.
052: *
053: * @author Sun
054: * @author Andrej Golovnin
055: * @version $Revision: 1.5 $
056: */
057: public final class RGBGrayFilter extends RGBImageFilter {
058:
059: /**
060: * Overrides default constructor; prevents instantiation.
061: */
062: private RGBGrayFilter() {
063: canFilterIndexColorModel = true;
064: }
065:
066: /**
067: * Returns an icon with a disabled appearance. This method is used
068: * to generate a disabled icon when one has not been specified.
069: *
070: * @param component the component that will display the icon, may be null.
071: * @param icon the icon to generate disabled icon from.
072: * @return disabled icon, or null if a suitable icon can not be generated.
073: */
074: public static Icon getDisabledIcon(JComponent component, Icon icon) {
075: if ((icon == null) || (component == null)
076: || (icon.getIconWidth() == 0)
077: || (icon.getIconHeight() == 0)) {
078: return null;
079: }
080: Image img;
081: if (icon instanceof ImageIcon) {
082: img = ((ImageIcon) icon).getImage();
083: } else {
084: img = new BufferedImage(icon.getIconWidth(), icon
085: .getIconHeight(), BufferedImage.TYPE_INT_ARGB);
086: icon.paintIcon(component, img.getGraphics(), 0, 0);
087: }
088: if (!Options.isHiResGrayFilterEnabled()
089: || (Boolean.FALSE
090: .equals(component
091: .getClientProperty(Options.HI_RES_DISABLED_ICON_CLIENT_KEY)))) {
092: return new ImageIcon(GrayFilter.createDisabledImage(img));
093: }
094:
095: ImageProducer producer = new FilteredImageSource(img
096: .getSource(), new RGBGrayFilter());
097:
098: return new ImageIcon(component.createImage(producer));
099: }
100:
101: /**
102: * Converts a single input pixel in the default RGB ColorModel to a single
103: * gray pixel.
104: *
105: * @param x the horizontal pixel coordinate
106: * @param y the vertical pixel coordinate
107: * @param rgb the integer pixel representation in the default RGB color model
108: * @return a gray pixel in the default RGB color model.
109: *
110: * @see ColorModel#getRGBdefault
111: * @see #filterRGBPixels
112: */
113: public int filterRGB(int x, int y, int rgb) {
114: // Find the average of red, green, and blue.
115: float avg = (((rgb >> 16) & 0xff) / 255f + ((rgb >> 8) & 0xff)
116: / 255f + (rgb & 0xff) / 255f) / 3;
117: // Pull out the alpha channel.
118: float alpha = (((rgb >> 24) & 0xff) / 255f);
119:
120: // Calculate the average.
121: // Sun's formula: Math.min(1.0f, (1f - avg) / (100.0f / 35.0f) + avg);
122: // Andrej: the following formula uses less operations and hence is faster.
123: avg = Math.min(1.0f, 0.35f + 0.65f * avg);
124: // Turn back into RGB.
125: int rgbval = (int) (alpha * 255f) << 24
126: | (int) (avg * 255f) << 16 | (int) (avg * 255f) << 8
127: | (int) (avg * 255f);
128: return rgbval;
129: }
130:
131: }
|