Gauge Beans Tutorial

Table of Contents


Introduction

In this tutorial, you use the Gauge Bean APIs to create a Thermometer gauge, restrict its value range, tailor the colors used, and specify a prefix and suffix for the displayed value. You then apply an under-damped synchronization to the gauge in order to have the thermometer mercury oscillate about the new gauge value before settling down. You then look at the two ways of updating the gauge value, and an explanation of how to receive notification of a gauge's value change.

Finally, we offer a few words of advice for those planning to implement their own gauges.

Creating a Thermometer Gauge

All gauges have a number of constructors, including a default constructor with no parameters, and at least one other constructor that allows most or all of the gauge properties to be passed in. Additionally, gauge properties have accessors to allow them to be set and retrieved.

All gauges have at least two constructors: a default constructor that takes no arguments, and assignes default values to all the gauge properties; and an alternative rich constructor that allows most of the gauge properties to be specified as arguments. Here you can see the rich constructor on the Thermometer gauge. This code could be within the constructor or addNotify() method of a class that extends: com.sun.java.swing.JComponent. The following code creates the Thermometer shown below.

  setBackground(                 // Set our background color.  *
    new Color(200, 200, 250));
                                 // Construct a Thermometer... *
  fThermometer = new com.ibm.eou.toolkit.gauge.Thermometer(
    72,                          // Initial value.             *
    0,                           // Minimum value.             *
    100,                         // Maximum value.             *
    30,                          // Tube width in pixels.      *
    "My Thermometer",            // Title to be displayed.     *
    new Color(220, 220, 250),    // Tube color.                *
    new Color(120,   0,   0),    // Mercury color.             *
    true,                        // Scale is required.         *
    new Color(  0, 220,   0),    // Colors for indicator bands *
    new Color(220, 220,   0),    //  above and below crossover *
                                 //  value.                    *
    50,                          // Crossover value.           *
    null,                        // No value prefix.           *
    "\u00BAC");                  // Value suffix (degrees C).  *

  add(fThermometer);             // Add Thermometer to our set *
                                 //  of children.              *

Example Thermometer

Applying a Synchronization

Let's say you want to have the mercury in the Thermometer oscillate before settling on each new value. You replace the default synchronization with another of the supplied synchronizations. The InertialSynchronization class provides for various degrees of damping.

The code below constructs an intertial synchronization with a natural period (the time to complete one oscillation) of 50 milliseconds, and a damping value of 0.4. Damping values under 1.0 are under damped, values greater than 1.0 are over damped, and a value of 1.0 is critically damped. The best way to visualize the effects of damping is to connect the GaugeTest bean to the Needle bean and then modify the damping property of the needle gauge.

 
  fThermometer.                       // Achieve under-damping with *
    setGaugeSynchronization(          //  an inertial               *
      new InertialSynchronization(    //  synchronization.          *
        50D,                          //  Natural period (ms).      *
        0.4D));                       //  Damping.                  *

Setting the Gauge Value

You can set a gauge's value:

You set the value directly using the setValue() method, supplying the new value. You use the accumulator technique by first setting an accumulator interval using the setAccumulatorInterval() method, enabling accumulation using the setAccumulatorEnabled() method, and then causing accumulator incrementation using the accumulate() method. The code below sets the value directly, followed by the establishment of an accumulator interval and the simulation of accumulator events by simply calling accumulate() in a loop. At the end of each accumulator interval the gauge updates its value to the accumulator count before resetting the count to zero.


  fThermometer.                         // Set the Thermometer value. *
    setValue(22);
  fThermometer.                         // Set the accumulator        *
    setAccumulatorInterval(1000);       //  interval to one second.   *
  fThermometer.                         // Enable accumulation.       *
    setAccumulatorEnabled(true);
  for (int i = 0; i < 50; i++)          // Trigger gauge accumulation *
  {                                     //  fifty times.              * 
    fThermometer.accumulate(); 
  } 

When you enable accumulation, a timer starts to automatically trigger the setting of the gauge value and resetting of the accumulator total. To stop this timer you disable accumulation.

Handling Events

The Thermometer gauge lets the user directly set the value. You set the boolean editable property set to true to enable mouse interaction. Once enabled, you can use the mouse to drag the Thermometer mercury level. Under these circumstances you might want to monitor changes in the gauge value. Monitoring gauge value changes is supported for all gauges via a standard listener mechanism.

You can add any class implementing the java.awt.event.AdjustmentListener interface to the set of listeners to receive gauge value change notification. You use the addAdjustmentListener() and removeAdjustmentListener() methods to do this. Refer to the java.awt.event.AdjustmentListener documentation for more details.

The following code shows how to listen for changes in a gauge value.


import com.ibm.eou.toolkit.gauge.*;
class      myClass
implements java.awt.event.AdjustmentListener
{
  private NeedleGauge fNeedleGauge;

  public myClass()
  {
    fNeedleGauge = new NeedleGauge(); // Construct a NeedleGauge.   *
    fNeedleGauge.                     // Allow gauge value changing *
      setEditable(true);              //  by user interaction.      *
    fNeedleGauge.                     // Listen for value changes.  *
      addAdjustmentListener(this);
  }

  public void adjustmentValueChanged( // Called when gauge value    *
    AdjustmentEvent event)            //  changes.                  *
  {
    int newValue = event.getValue();  // Save the new gauge value.  *
  }
}

Using a Gauge Model

With the advent of Swing gauges, all gauges have a gauge model representing the current value and the range minimum and maximum. This model can be obtained using the getModel() method. Gauge models may be monitored for value and range changes using a new listening mechanism.

You can add any class implementing the com.ibm.eou.toolkit.gauge.GaugeModelListener interface to the set of listeners to receive gauge model change notification. You use the addGaugeModelListener() and removeGaugeModelListener() methods to do this.

Gauge model listeners receive change notifications via their gaugeModelChanged() method. The GaugeModelChangeEvent object passed with this method carries the current and previous value and range limits for the gauge model, as well as methods that can be called to see which of these has changed.

The following code shows how to listen for changes in a gauge model.


import com.ibm.eou.toolkit.gauge.*;
class      myClass
implements com.ibm.eou.toolkit.gauge.GaugeModelListener
{
  private NeedleGauge fNeedleGauge;
  private GaugeModel  fGaugeModel;

  public myClass()
  {
    fNeedleGauge = new NeedleGauge(); // Construct a NeedleGauge.   *
    
    fGaugeModel =                     // Obtain a reference to its  *
      fNeedleGauge.getModel();        //  model.                    *
    fGaugeModel.                      // Listen for model changes.  *
      addGaugeModelListener(this);
  }

  public void gaugeModelChanged(      // Called when gauge model    *
    GaugeModelChangeEvent event)      //  changes.                  *
  {
    int newValue = event.getValue();  // Save the new gauge model   *
  }                                   //  value.                    * 
}

Creating your Own Gauges

The Gauge Interface:  The Gauge interface can be implemented by anything that has the characteristics of a gauge, namely that it displays a value from a range and that the value can change continually. The interface defines setValue(), setMinimum(), setMaximum() methods for setting the value and range of the gauge, and getValue(), getMinimum(), getMaximum() methods for querying the value and range. The  synchronize() method waits for the gauge display to become up-to-date. This is important, because a well-behaved gauge should immediately return from the setValue() method even if the gauge takes some time to display the new value, so the synchronize() method is the only way to be sure that the current gauge value is actually being shown to the user.

To build well-behaved, fully-functional gauges with your own visual presentation, extend the BaseGauge class.

The BaseGauge Class:  In order to make it easy to implement well-behaved gauges, BaseGauge class implements the Gauge interface, and manages the setting and maintaining of the gauge value. It also provides for gauges that take some time to display the new gauge value (because of some animation effect), automatically handled on a background thread.

Extending BaseGauge to build your own gauge is easy, you just need to specify the visual presentation of your gauge, and the update behavior.

Visual Presentation: Implement a single abstract protected method defined by BaseGauge in your extending class. This method is a form of paint(), which takes a number of parameters telling the method exactly what it has to render onto the screen.

Behavior:  Provide the BaseGauge with an implementation of the GaugeSynchronization interface. Several implementations are provided that give common gauge behaviors, or you can provide your own implementation of this interface to achieve custom behavior. Provide any implementation of GaugeSynchronization via the setGaugeSynchronization() method of BaseGauge. By default, BaseGauge uses an immediate synchronization, so that new gauge values are displayed at once. So if immediate synchronization is appropriate for your gauge, you only need to implement the required paint method.

The GaugeModel Interface:  In keeping with other Swing components, Gauges now use a model to manage their value and value ranges. The GaugeModel interface prescribes the methods that a gauge model must implement. The DefaultGaugeModel class provides a default implementation of this interface, and is used when a gauge model is not explicitly provided.

Access the gauge model for a gauge using the getModel() method, and replace it using the setModel() method. As well as acting as an AdjustmentListener to detect gauge changes, you can also act as a GaugeModelListener to receive notification of any change to the gauge value or range. Both of these mechanisms are explained in more detail above.


Copyright © IBM Corporation 1998, 1999. All Rights Reserved