\ru\ifmo\alarm\gui\CarPanel.java

package ru.ifmo.alarm.gui; 
 
import java.awt.Graphics; 
 
import java.awt.Cursor; 
import java.awt.image.BufferedImage; 
import java.awt.image.PixelGrabber; 
 
import java.io.IOException; 
 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
 
import ru.ifmo.alarm.controlled.LightDiode; 
import ru.ifmo.alarm.controlled.Lights; 
 
public class CarPanel extends JPanel { 
    static final long serialVersionUID = 0;     //eclipse wants me to write this :( 
     
    private static final String IMG_PATH = "/ru/ifmo/alarm/img/"; 
    private static final String c4onFileName  = "c4on.jpg"; 
    private static final String c4offFileName = "c4off.jpg"; 
    private static final String c4MaskFileName = "c4mask.bmp"; 
    private static final String lightDiodeOnFileName  = "lightDiodeOn.jpg"; 
    private static final String lightDiodeOffFileName = "lightDiodeOff.jpg"; 
     
    protected JLabel carLabel; 
    protected JLabel diodeLabel; 
     
    protected ImageIcon carOnIcon; 
    protected ImageIcon carOffIcon; 
    protected ImageIcon diodeOnIcon; 
    protected ImageIcon diodeOffIcon; 
     
    private boolean[][] carMask; 
     
    public CarPanel() { 
        this.setLayout(null); 
         
        // load all images 
        carOnIcon = new ImageIcon( 
                CarPanel.class.getResource(IMG_PATH + c4onFileName)); 
        carOffIcon = new ImageIcon( 
                CarPanel.class.getResource(IMG_PATH + c4offFileName)); 
        diodeOnIcon  = new ImageIcon( 
                CarPanel.class.getResource(IMG_PATH + lightDiodeOnFileName)); 
        diodeOffIcon = new ImageIcon( 
                CarPanel.class.getResource(IMG_PATH + lightDiodeOffFileName)); 
         
        // load car mask 
        loadCarMask(); 
         
        // add car label on panel 
        carLabel = new JLabel(); 
            this.add(carLabel); 
            carLabel.setBounds(0, 0, carOnIcon.getIconWidth(), carOnIcon.getIconHeight()); 
            carLabel.setLayout(null); 
            carLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); 
         
        //this.setSize(carOffIcon.getIconWidth(), carOffIcon.getIconHeight()); 
         
        // add diode label on panel 
        diodeLabel = new JLabel(); 
            carLabel.add(diodeLabel); 
            diodeLabel.setSize(diodeOnIcon.getIconWidth(), diodeOnIcon.getIconHeight()); 
            diodeLabel.setBounds(80, 245, diodeLabel.getWidth(), diodeLabel.getHeight()); 
         
        this.setSize(carOnIcon.getIconWidth(), carOnIcon.getIconHeight()); 
    } 
     
    public void paint(Graphics g) { 
        if (Lights.isOn()) { 
            carLabel.setIcon(carOnIcon); 
            //carOnIcon.paintIcon (this, g, 0, 0); 
        } else { 
            carLabel.setIcon(carOffIcon); 
            //carOffIcon.paintIcon(this, g, 0, 0); 
        } 
        if (LightDiode.isOn()) 
        { 
            diodeLabel.setIcon(diodeOnIcon); 
        } else 
        { 
            diodeLabel.setIcon(diodeOffIcon); 
        } 
         
        super.paint(g); 
    } 
     
    private boolean loadCarMask() { 
        carMask = null; 
        BufferedImage buf = null; 
        try { 
            buf = ImageIO.read( 
                    CarPanel.class.getResource(IMG_PATH + c4MaskFileName)); 
        } catch (IOException e) { 
            System.out.println("Couldn't create BufferedImage"); 
            e.printStackTrace(); 
            return false; 
        } catch (IllegalArgumentException 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) { 
            System.out.println("Couldn't grab pixels"); 
            e.printStackTrace(); 
            return false; 
        } 
        carMask = 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 alpha = (pixel >> 24) & 0xff; 
                int red   = (pixel >> 16) & 0xff; 
                int green = (pixel >>  8) & 0xff; 
                int blue  = (pixel      ) & 0xff; 
                if (red + green + blue > (256 / 2) * 3) { 
                    carMask[i][j] = false;  // the pixel was almost white => out of the car area 
                } else { 
                    carMask[i][j] = true;   // the pixel was almost black => in the car area 
                } 
            } 
        } 
        return true; 
    } 
     
    // this method is overriden, so that shape of car won't be rectangular 
    public boolean contains(int x, int y) { 
        try { 
            return carMask[x][y]; 
        } catch (NullPointerException e) { 
            return super.contains(x, y); 
        } catch (ArrayIndexOutOfBoundsException e) { 
            return super.contains(x, y); 
        } 
    } 
}