Monitoring State Changes Using ObserverObservable

   

Monitoring State Changes Using Observer / Observable

As you will see in later chapters, Java relies heavily on the Model-View-Controller (MVC) paradigm. MVC stresses that data (a model) should be unaware of how it is used and displayed (by views), and that a third party (a controller) should coordinate their interaction. This chapter serves as a prelude to those concepts by introducing observables and observers.

The Observable Class

The Observable class allows an object to notify other objects when it changes. The concept of observables is borrowed from Smalltalk. In Smalltalk, an object can express interest in another object, meaning that it would like to know when the other object changes.

When building user interfaces, you might have multiple ways to change a piece of data, and changing that data might cause several different parts of the display to update. For instance, suppose that you want to create a scrollbar that changes an integer value and, in turn , that integer value is displayed on some sort of graphical meter. You want the meter to update as the value is changed, but you don't want the meter to know anything about the scrollbar. If you are wondering why the meter shouldn't know about the scrollbar, what happens if you decide you don't want a scrollbar, but instead want the number entered from a text field? You shouldn't have to change the meter every time you change the input source.

In this example, you would be better off creating an integer variable that is observable. This observable integer could notify any interested objects (called observers ) of changes in its value without being concerned about how many or what type of objects are interested in this in formation. In the case of the graphical meter, it would be informed that the value changed and would query the integer variable for the new value and then redraw itself. This allows the meter to display the value correctly, no matter what mechanism is used to change the value.

From an MVC standpoint, the integer variable can be classified as a model. The graphical meter is an example of a view. The scrollbar is both a controller and a view because it modifies the value as it is moved, and it depicts the current value using the scrollbar position.

You create an observable object using a subclass of Observable. You can then register and report changes using the setChanged and notifyObservers methods . The setChanged method marks the observable as having been changed:

 protected synchronized void setChanged() 

This method sets an internal changed flag that is used by the notifyObservers method. It is automatically cleared when notifyObservers is called, but you can also clear it manually with the clearChanged method:

 protected synchronized void clearChanged() 

The notifyObservers method checks to see whether the changed flag has been set, and if so, sends a notification to each registered observer:

 public void notifyObservers() 

The notifyObservers method can also be called with an argument to pass additional information about the change, such as the new value assigned to the observable:

 public void notifyObservers(Object arg) 

You can determine whether an observable has changed by calling the hasChanged method:

 public synchronized boolean hasChanged() 

Observers register interest in an observable by calling the addObserver method:

 public synchronized void addObserver(Observer obs) 

Observers de-register interest in an observable by calling deleteObserver :

 public synchronized void deleteObserver(Observer obs) 

An observable can also clear out its list of observers by calling the deleteObservers method:

 public synchronized void deleteObservers() 

The countObservers method returns the number of observers registered for an observable:

 public synchronized int countObservers() 

Listing 10.6 shows an example implementation of an ObservableInt class.

Listing 10.6 ObservableInt.java ” Example of an Observable
 import java.util.*; public class ObservableInt extends Observable {   int value;     // The value everyone wants to observe   public ObservableInt() {   }   public ObservableInt(int newValue) {     value = newValue;   }   public synchronized void setValue(int newValue) {     //     // Check to see that this call is REALLY changing the value     //     if (newValue != value) {       value = newValue;       setChanged();       notifyObservers();     }   }   public synchronized int getValue() {     return value;   } } 

The Observer Interface

The Observable class has a companion interface called Observer. Any class that wants to receive updates about a change in an observable needs to implement the Observer interface. This interface consists of a single method called update that is called when an object changes:

 public abstract void update(Observable obs, Object arg); 

The Object argument is a value passed by the observable when it called notifyObservers. If notifyObservers is called with no arguments, this reference is null.

Listing 10.7 shows an example of a JLabel class that implements the Observer interface so that it can be informed of changes in an integer variable and update itself with the new value.

Listing 10.7 IntLabel.java ” An Example Observer
 import javax.swing.*; import java.util.*; public class IntLabel extends JLabel implements Observer {   private ObservableInt intValue;     // The value being observed   public IntLabel(ObservableInt theInt) {     intValue = theInt;     // Tell intValue you're interested in it     intValue.addObserver(this);     // Initialize the label to the current value of intValue     setText( "" + intValue.getValue() );   }   // Update will be called whenever intValue is changed, so just update   // the label text.   public void update(Observable obs, Object arg) {     setText( "" + intValue.getValue() );   } } 
   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net