/*
Violet - A program for editing UML diagrams.
Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
Alexandre de Pellegrin (http://alexdp.free.fr);
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.horstmann.violet.framework.swingextension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.AreaAveragingScaleFilter;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.awt.image.ReplicateScaleFilter;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.IconUIResource;
import javax.swing.plaf.basic.BasicButtonUI;
public class IconButtonUI extends BasicButtonUI
{
public IconButtonUI()
{
super();
}
public IconButtonUI(double scalingValue) {
this.scalingValue = scalingValue;
}
protected void installDefaults(AbstractButton b)
{
super.installDefaults(b);
b.setOpaque(false);
b.setBorderPainted(false);
b.setRolloverEnabled(true);
b.setBorder(new EmptyBorder(0, 0, 0, 0));
prepareIcons(b);
}
@Override
public void installUI(JComponent c)
{
AbstractButton b = (AbstractButton) c;
this.originalIcon = b.getIcon();
super.installUI(c);
}
@Override
public void uninstallUI(JComponent c)
{
AbstractButton b = (AbstractButton) c;
b.setIcon(this.originalIcon);
super.uninstallUI(c);
}
public void paint(Graphics g, JComponent c)
{
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
if (model.isArmed() && model.isPressed())
{
b.setIcon(darkerIcon);
}
else if (model.isRollover())
{
b.setIcon(brighterIcon);
}
else
{
b.setIcon(baseIcon);
}
super.paint(g, c);
}
/**
* Prepares icons to simulate button behaviour
*/
private void prepareIcons(AbstractButton b)
{
baseIcon = b.getIcon();
Image baseImage = getImage(baseIcon);
if (this.scalingValue > 0) {
baseImage = getScaledImage(baseImage,(int) (baseIcon.getIconWidth() * this.scalingValue), (int) (baseIcon.getIconHeight() * this.scalingValue));
baseIcon = getIcon(baseImage);
}
Image brightenImage = changeBrightness(baseImage, true, 30);
Image darkenImage = changeBrightness(baseImage, false, 20);
brighterIcon = getIcon(brightenImage);
darkerIcon = getIcon(darkenImage);
}
/**
* Creates an image from an icon.
*/
private Image getImage(Icon icon)
{
if (icon instanceof ImageIcon)
{
return ((ImageIcon) icon).getImage();
}
else
{
BufferedImage buffer = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = buffer.getGraphics();
icon.paintIcon(new JLabel(), g, 0, 0);
g.dispose();
return buffer;
}
}
/**
* @param img
* @return an icon from an image
*/
private Icon getIcon(Image img)
{
return new IconUIResource(new ImageIcon(img));
}
/**
* @param img to scale
* @param newWidth desired width
* @param newHeight desired height
* @return a scaled image
*/
private Image getScaledImage(Image img, int newWidth, int newHeight) {
ImageFilter filter = new AreaAveragingScaleFilter(newWidth, newHeight);
ImageProducer prod = new FilteredImageSource(img.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(prod);
}
/**
* Change the brightness of an image
*/
private Image changeBrightness(Image img, final boolean brighten, final int percent)
{
ImageFilter filter = new RGBImageFilter()
{
/*
* (non-Javadoc)
*
* @see java.awt.image.RGBImageFilter#filterRGB(int, int, int)
*/
public int filterRGB(int x, int y, int rgb)
{
return (rgb & 0xff000000) | (filter(rgb >> 16) << 16) | (filter(rgb >> 8) << 8) | (filter(rgb));
}
/**
* Brighens or darkens a single r/g/b value.
*/
private int filter(int color)
{
color = color & 0xff;
if (brighten)
{
color = (255 - ((255 - color) * (100 - percent) / 100));
}
else
{
color = (color * (100 - percent) / 100);
}
if (color < 0) color = 0;
if (color > 255) color = 255;
return color;
}
};
ImageProducer prod = new FilteredImageSource(img.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(prod);
}
private Icon baseIcon;
private Icon darkerIcon;
private Icon brighterIcon;
private Icon originalIcon;
/**
* Allows to scale icon image
*/
private double scalingValue = -1;
}