FileDocCategorySizeDatePackage
Thermostat.javaAPI DocExample16663Sun Jan 04 21:14:46 GMT 1998BeansBook.Simulator

Thermostat

public class Thermostat extends Panel implements PropertyChangeListener, ActionListener, ItemListener

Fields Summary
protected Choice
unitsChoice
protected Choice
displayChoice
protected Button
decButton
protected Button
incButton
protected Label
displayLabel
protected boolean
bNeedsCooling
protected boolean
bNeedsHeating
protected double
comfortTemp
protected double
ambientTemp
protected boolean
bShowingAmbient
protected boolean
bShowingCelsius
protected VetoableChangeSupport
vetoSupport
protected transient Vector
coolingListeners
protected transient Vector
heatingListeners
Constructors Summary
public Thermostat()


   // constructor
    
   
      // call superclass constructor
      super();
      
      // create the support object for constrained properties
      vetoSupport = new VetoableChangeSupport(this);
      
      // use a border layout for the constituents
      setLayout(new BorderLayout());
      
      // create the constituents
      unitsChoice = new Choice();
      displayChoice = new Choice();
      decButton = new Button("<<");
      incButton = new Button(">>");
      displayLabel = new Label("**********");

      // register as action listener for the buttons
      decButton.addActionListener(this);
      incButton.addActionListener(this);
      
      // register as item listener for the choice controls
      displayChoice.addItemListener(this);
      unitsChoice.addItemListener(this);
      
      // disable the comfort temperature buttons
      decButton.setEnabled(false);
      incButton.setEnabled(false);

      // add the constituents in their appropriate locations
      add(unitsChoice, BorderLayout.NORTH);
      add(displayChoice, BorderLayout.SOUTH);
      add(decButton, BorderLayout.WEST);
      add(incButton, BorderLayout.EAST);
      add(displayLabel, BorderLayout.CENTER);
      
      // use center alignment for the temperature display
      displayLabel.setAlignment(Label.CENTER);
      
      // add the units to the choice control
      unitsChoice.add("Celsius");
      unitsChoice.add("Fahrenheit");
      
      // add the display types to the choice control
      displayChoice.add("Ambient");
      displayChoice.add("Comfort");
   
Methods Summary
public voidactionPerformed(java.awt.event.ActionEvent evt)

      // change in temperature
      double tempDelta;
      
      // delta value for rounding
      double roundingDelta;
      
      // it was the decrement button
      if (evt.getSource() == decButton)
      {
         // reduce temp by 1
         tempDelta = -1.0;
         
         // delta is 0 for rounding down
         roundingDelta = 0.0;
      }
      else // it was the increment button
      {
         // increase temp by 1
         tempDelta = 1.0;
         
         // delta is 1 for rounding up
         roundingDelta = 1.0;
      }

      // the new proposed comfort temperature
      double newValue;
      
      // displaying temperatures in Celsius
      if (bShowingCelsius)
      {
         // just add the delta
         newValue = comfortTemp + tempDelta;
      }
      else // displaying in Fahrenheit
      {
         // convert to Fahrenheit, add the delta, and convert back
         double t = 32.0 + ((comfortTemp * 9.0) / 5.0);
         t += tempDelta;
         newValue = (t - 32.0) * 5.0 / 9.0; 
      }
      
      // the old value object for firing the vetoable change event
      Double old = new Double(comfortTemp);
      try
      {
         // fire the event
         vetoSupport.fireVetoableChange("ComfortTemperature", old, new  
                                 Double(newValue));
         
         // if we get this far we can make the change
         synchronized (this)
         {
            comfortTemp = newValue;
         }
      }
      catch (PropertyVetoException e)
      {
         // the change was vetoed by a listening object, but
         // if we have a fractional part, we could try rounding the value
         // to use a whole number
         double wholePart = (double)old.longValue();
         if ((old.doubleValue() - wholePart) == 0.0)
         {
            // we can't make a change
            return;
         }
             
         // attempt to alter the comfort temperature using the whole part of the
         // old value and the rounding delta
         newValue = wholePart + roundingDelta;
         
         try
         {
            // fire the event
            vetoSupport.fireVetoableChange("ComfortTemperature", old, 
                                 new Double(newValue));
         }
         catch (PropertyVetoException ee)
         {
            // we couldnt make this change either
            return;
         }

         // we can go ahead and change it now
         synchronized (this)
         {
            comfortTemp = wholePart + roundingDelta;
         }
      }

      // set the needs cooling and needs heating states, comparing 
      // the ambient and comfort level temperatures
      setNeedsCooling((ambientTemp > comfortTemp) && 
                      ((ambientTemp - comfortTemp) >= 1.0));
      setNeedsHeating((ambientTemp < comfortTemp) && 
                      ((comfortTemp - ambientTemp) >= 1.0));

      // redisplay the temperature
      displayTemp();
   
public synchronized voidaddCoolingRequestListener(CoolingRequestListener l)

      // add a listener if it is not already registered
      if (coolingListeners == null)
      {
         coolingListeners = new Vector();
      }

      if (!coolingListeners.contains(l))
      {
         coolingListeners.addElement(l);
      }
   
public synchronized voidaddHeatingRequestListener(HeatingRequestListener l)

      // add a listener if it is not already registered
      if (heatingListeners == null)
      {
         heatingListeners = new Vector();
      }
      
      if (!heatingListeners.contains(l))
      {
         heatingListeners.addElement(l);
      }
   
public voidaddVetoableChangeListener(java.beans.VetoableChangeListener l)

      vetoSupport.addVetoableChangeListener(l);
   
protected voiddisplayTemp()

      // temporary temperature value
      double t;
      if (bShowingAmbient)
      {
         // use the ambient temperature
         t = ambientTemp;
      }
      else
      {
         // use the comfort level temperature
         t = comfortTemp;
      }
      
      // if not using Celsius, convert to Fahrenheit
      if (!bShowingCelsius)
      {
         t = 32.0 + ((t * 9.0) / 5.0);
      }
      
      // display whole number part of the temperature
      Double d = new Double(t);
      displayLabel.setText(new Long(d.longValue()).toString());
   
public synchronized doublegetComfortTemperature()

      return comfortTemp;
   
public voiditemStateChanged(java.awt.event.ItemEvent evt)

      if (evt.getSource() == displayChoice &&
           evt.getStateChange() == ItemEvent.SELECTED)
      {
         // determine the newly selected item string
         String sel = (String)evt.getItem();
         if (sel.equals("Comfort"))
         {
            // showing comfort level, not ambient
            bShowingAmbient = false;
            
            // enable comfort level buttons
            decButton.setEnabled(true);
            incButton.setEnabled(true);
            
            // display the temperature
            displayTemp();
         }
         else if (sel.equals("Ambient"))
         {
            // showing ambient temperature
            bShowingAmbient = true;
            
            // disable the comfort level buttons
            decButton.setEnabled(false);
            incButton.setEnabled(false);
            
            // display the temperature
            displayTemp();
         }
      }

      else if (evt.getSource() == unitsChoice &&
           evt.getStateChange() == ItemEvent.SELECTED)
      {
         // a new temperature units item has been selected
         Choice pp = (Choice)evt.getSource();
         
         // determine the newly selected item string
         String sel = (String)evt.getItem();
         if (sel.equals("Celsius"))
         {
            // showing Celsius
            bShowingCelsius = true;
            
            // display the temperature
            displayTemp();
         }
         else if (sel.equals("Fahrenheit"))
         {
            // showing Fahrenheit, not Celsius
            bShowingCelsius = false;
            
            // display the temperature
            displayTemp();
         }
      }
   
public voidpropertyChange(java.beans.PropertyChangeEvent evt)

      // check for a Temperature property change
      if (evt.getPropertyName().equals("Temperature"))
      {
         // modify the ambient temperature
         Double d = (Double)evt.getNewValue();
         ambientTemp = d.doubleValue();
         
         // update the bNeedsCooling and bNeedsHeating variables
         setNeedsCooling((ambientTemp > comfortTemp) && 
                        ((ambientTemp - comfortTemp) >= 1.0));
         setNeedsHeating((ambientTemp < comfortTemp) && 
                        ((comfortTemp - ambientTemp) >= 1.0));
         
         // display the temperature
         displayTemp();
      }
   
private voidreadObject(java.io.ObjectInputStream stream)

      try
      {
         stream.defaultReadObject();
         
         Object l;

         // get the cooling request listeners
         while(null != (l = stream.readObject())) 
         {
            addCoolingRequestListener((CoolingRequestListener)l);
         }

         // get the heating request listeners
         while(null != (l = stream.readObject())) 
         {
            addHeatingRequestListener((HeatingRequestListener)l);
         }
      }
      catch (ClassNotFoundException e)
      {
         throw new IOException();
      }
   
public synchronized voidremoveCoolingRequestListener(CoolingRequestListener l)

      // remove it if it is registered
      if (coolingListeners != null)
      {
         coolingListeners.removeElement(l);
      }  
   
public synchronized voidremoveHeatingRequestListener(HeatingRequestListener l)

      // remove it if it is registered
      if (heatingListeners != null)
      {
         heatingListeners.removeElement(l);
      }  
   
public voidremoveVetoableChangeListener(java.beans.VetoableChangeListener l)

      vetoSupport.removeVetoableChangeListener(l);
   
private voidsetNeedsCooling(boolean b)

      // do nothing if there is no change
      if (b == bNeedsCooling)
      {
         return;
      }

      bNeedsCooling = b;

      // nothing else to do if collection isnt allocated yet      
      if (coolingListeners == null)
      {
         return;
      }
      
      // fire the cooling service request
      ServiceRequestEvent evt = new ServiceRequestEvent(this, bNeedsCooling);
      
      // make a copy of the listener object vector so that it cannot
      // be changed while we are firing events
      Vector v;
      synchronized(this)
      {
         v = (Vector) coolingListeners.clone();
      }

      // fire the event to all listeners
      int cnt = v.size();
      for (int i = 0; i < cnt; i++)
      {
         CoolingRequestListener client = (CoolingRequestListener)v.elementAt(i);
         client.coolingRequest(evt);
      }
   
private voidsetNeedsHeating(boolean b)

      // do nothing if there is no change
      if (b == bNeedsHeating)
      {
         return;
      }

      bNeedsHeating = b;

      // nothing else to do if collection isnt allocated yet
      if (heatingListeners == null)
      {
         return;
      }
            
      // fire the heating service request
      ServiceRequestEvent evt = new ServiceRequestEvent(this, bNeedsHeating);
      
      // make a copy of the listener object vector so that it cannot
      // be changed while we are firing events
      Vector v;
      synchronized(this)
      {
         v = (Vector) heatingListeners.clone();
      }

      // fire the event to all listeners
      int cnt = v.size();
      for (int i = 0; i < cnt; i++)
      {
         HeatingRequestListener client = (HeatingRequestListener)v.elementAt(i);
         client.heatingRequest(evt);
      }
   
private voidwriteObject(java.io.ObjectOutputStream stream)

      // perform default writing first
      stream.defaultWriteObject();

      // if we have allocated coolingListeners
      if (coolingListeners != null)
      {
         // clone the vector in case one is added or removed
         Vector v = null;
         synchronized (this) 
         {
            v = (Vector) coolingListeners.clone();
         }

         int cnt = v.size();
         for(int i = 0; i < cnt; i++) 
         {
            // get the listener element from the collection
            CoolingRequestListener l = 
            (CoolingRequestListener)v.elementAt(i);
            
            // if the listener is serializable, write it to the stream
            if (l instanceof Serializable) 
            {
               stream.writeObject(l);
            }
         }
      }
      
      // a null object marks the end of the cooling request listeners 
      stream.writeObject(null);

      // if we have allocated heatingListeners
      if (heatingListeners != null)
      {
         // clone the vector in case one is added or removed
         Vector v = null;
         synchronized (this) 
         {
            v = (Vector) heatingListeners.clone();
         }

         int cnt = v.size();
         for(int i = 0; i < cnt; i++) 
         {
            // get the listener element from the collection
            HeatingRequestListener l = 
            (HeatingRequestListener)v.elementAt(i);
            
            // if the listener is serializable, write it to the stream
            if (l instanceof Serializable) 
            {
               stream.writeObject(l);
            }
         }
      }
      
      // a null object marks the end of the heating request listeners 
      stream.writeObject(null);