/* LightedPushButton.java */

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.beans.*;

public class LightedPushButton
extends Canvas
implements Serializable
{
  //---Instanzvariablen----------------------------------------
  protected Color                 linecolor;
  protected Color                 framecolor;
  protected Color                 lightoncolor;
  protected Color                 lightoffcolor;
  protected boolean               lighton;
  transient protected PropertyChangeSupport pchglisteners;
  transient protected VetoableChangeSupport vchglisteners;

  //---Methoden------------------------------------------------
  public LightedPushButton()
  {
    linecolor     = Color.black;
    framecolor    = Color.darkGray;
    lightoncolor  = Color.red;
    lightoffcolor = new Color(127, 0, 0); //dark red
    lighton       = false;
    initTransientState();
  }

  //---Zustandsumschaltung Licht an/aus---
  public void setLightOn(boolean on)
  throws PropertyVetoException
  {
    boolean oldvalue = this.lighton;
    vchglisteners.fireVetoableChange("lighton", oldvalue, on);
    this.lighton = on;
    if (oldvalue != on) {
      repaint();
    }
    pchglisteners.firePropertyChange("lighton", oldvalue, on);
  }

  public boolean getLightOn()
  {
    return this.lighton;
  }

  //---Verwaltung der PropertyChangeListener---
  public void addPropertyChangeListener(PropertyChangeListener l)
  {
    pchglisteners.addPropertyChangeListener(l);
  }

  public void removePropertyChangeListener(PropertyChangeListener l)
  {
    pchglisteners.removePropertyChangeListener(l);
  }

  //---Verwaltung der VetoableChangeListener---
  public void addVetoableChangeListener(VetoableChangeListener l)
  {
    vchglisteners.addVetoableChangeListener(l);
  }

  public void removeVetoableChangeListener(VetoableChangeListener l)
  {
    vchglisteners.removeVetoableChangeListener(l);
  }

  //---Implementierung der Oberfläche---
  public void paint(Graphics g)
  {
    int width = getSize().width;
    int height = getSize().height;
    //Rahmen
    g.setColor(framecolor);
    g.fillOval(0, 0, width, height);
    //Beleuchtung
    g.setColor(lighton ? lightoncolor : lightoffcolor);
    g.fillOval(4, 4, width - 8, height - 8);
    //Konturlinien
    g.setColor(linecolor);
    g.drawOval(0, 0, width - 1, height - 1);
    g.drawOval(3, 3, width - 7, height - 7);
  }

  public Dimension getPreferredSize()
  {
    return new Dimension(32, 32);
  }

  public Dimension getMinimumSize()
  {
    return new Dimension(16, 16);
  }

  //---Private Klassen---------------------------------------
  /**
   * Initialisierung der nicht-persistenten Instanzvariablen.
   */
  private void initTransientState()
  {
    pchglisteners = new PropertyChangeSupport(this);
    vchglisteners = new VetoableChangeSupport(this);
    addMouseListener(new MouseClickAdapter());
  }

  /**
   * Wird überlagert, um nach dem Deserialisieren den transienten
   * Zustand zu initialisieren.
   */
  private void readObject(ObjectInputStream stream)
  throws IOException, ClassNotFoundException
  {
    stream.defaultReadObject();
    initTransientState();
  }

  //---Lokale Klassen----------------------------------------
  class MouseClickAdapter
  extends MouseAdapter
  {
    public void mouseClicked(MouseEvent event)
    {
      try {
        setLightOn(!getLightOn());
      } catch (PropertyVetoException e) {
        //no change if vetoed
      }
    }
  }
}