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

Thermostat.java

// This example is from the book Developing Java Beans by Robert Englander. 
// Copyright (c) 1997 O'Reilly & Associates.
// You may study, use, modify, and distribute this example for any purpose.
// This example is provided WITHOUT WARRANTY either expressed or implied.

// Chapter 8 -- The Thermostat class

package BeansBook.Simulator;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import java.io.*;

// the Thermostat bean class definition
public class Thermostat extends Panel  // subclasses Panel
    implements PropertyChangeListener, // property changes from temperature source
               ActionListener,         // action events from buttons
               ItemListener            // item events choice controls
{
   // the choice control for display units
   protected Choice unitsChoice;
   
   // the choice control for displaying ambient or comfort level temperature
   protected Choice displayChoice;
   
   // button for decrementing comfort level temperature
   protected Button decButton;
   
   // button for incrementing comfort level temperature
   protected Button incButton;
   
   // label for displaying temperatures
   protected Label  displayLabel;

   // flags for the NeedsCooling and NeedsHeating state
   protected boolean bNeedsCooling = false;
   protected boolean bNeedsHeating = false;
   
   // the comfort level temperature
   protected double comfortTemp = 22.0;
   
   // the ambient temperature from the temperature source
   protected double ambientTemp;
   
   // flag indicating if ambient temperature is being displayed
   protected boolean bShowingAmbient = true;
   
   // flag indicating if Celsius units are being displayed
   protected boolean bShowingCelsius = true;

   // support for the constrained properties
   protected VetoableChangeSupport vetoSupport;

   // cooling and heating request listeners
   protected transient Vector coolingListeners;
   protected transient Vector heatingListeners;

   // constructor
   public Thermostat()
   {
      // 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");
   }

   // handle an action event
   public void actionPerformed(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 couldn