\ru\ifmo\alarm\gui\ShapedButton.java

package ru.ifmo.alarm.gui; 
 
import java.awt.image.BufferedImage; 
import java.awt.image.PixelGrabber; 
import java.io.IOException; 
import java.net.URL; 
 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
 
public class ShapedButton extends JButton { 
    public static final long serialVersionUID = 0; 
     
    private boolean[][] shapeMask; 
     
    public ShapedButton(URL maskImagePath) { 
        super(); 
        shapeMask = null; 
        setMask(maskImagePath); 
    } 
     
    public ShapedButton() { 
        this(null); 
    } 
         
    public boolean setMask(URL maskImagePath) { 
        if (maskImagePath == null) 
            return false; 
        BufferedImage buf = null; 
         
        try { 
            buf = ImageIO.read(maskImagePath); 
        } catch (IOException e) { 
            return false; 
        } 
        if (buf == null)  
            return false; 
         
        int w = buf.getWidth(); 
        int h = buf.getHeight(); 
        int[] pixels = new int[w * h]; 
        PixelGrabber grabber = new PixelGrabber(buf, 0, 0, w, h, pixels, 0, w); 
        try { 
            grabber.grabPixels(); 
        } catch (InterruptedException e) { 
            return false; 
        } 
        shapeMask = new boolean[w][h]; 
        for (int j = 0; j < h; j++) { 
            for (int i = 0; i < w; i++) { 
                int pixel = pixels[j * w + i]; 
                int red   = (pixel >> 16) & 0xff; 
                int green = (pixel >>  8) & 0xff; 
                int blue  = (pixel      ) & 0xff; 
                if (red + green + blue > (256 / 2) * 3) { 
                    shapeMask[i][j] = false;  // the pixel was almost white => out of the button area 
                } else { 
                    shapeMask[i][j] = true;   // the pixel was almost black => in the button area 
                } 
            } 
        } 
        return true; 
    } 
     
    public boolean contains(int x, int y) { 
        try { 
            return shapeMask[x][y]; 
        } catch (NullPointerException e) { 
            return super.contains(x, y); 
        } catch (ArrayIndexOutOfBoundsException e) { 
            return super.contains(x, y); 
        } 
    } 
}