Skip to main content
Jump to: navigation, search

JFace Data Binding/Observable

Observables are one of the key abstractions provided by JFace Data Binding and are an implementation of the Observer pattern. They provide a common abstraction for observing changes in objects.

Core Interfaces of Interest

  • IObservable
  • IObservableValue
  • IVetoableValue
  • IObservableCollection
  • IObservableList
  • IObservableSet
  • IObservableMap

Implementation Design Principles

  1. An observable must remove listeners on the observed when disposed. For example if you registered selection listeners on a widget when the observable was constructed it must remove these on dispose of the observable.
  2. An observable should fire change events when the value changes if at all possible. This means when the value changes in the object being observed or when the value is set on the observable. One thing to look out for is firing multiple change events when this occurs. A use case where this arises is a widget that fires change events when the value is set programmatically (e.g. Text.setText(...)). In these use cases an 'updating' flag is normally employed.
  3. Not all observables fire change events. An example of this is Control.setEnabled(...) in SWT. If the object being observed doesn't fire change events when the value is set programmatically the observable cannot observe programmatic changes in the observed object. In these use cases it still pays to have the abstraction for get/set value but when coding against such observables it's good to be aware of this behavior. Because of this it's good to always set the value on the observable to ensure that change events are fired.
  4. In an observable when retrieving the value always retrieve it from the observed object. Don't cache the value in the observable if possible. Caching can cause issues if there's potential for this state to get out of sync like in the Control.setEnabled(...) use case mentioned above.
  5. If the observable is an IObservableValue and the type of the attribute is a primitive use the primitive class (e.g. Boolean.TYPE or boolean.class) rather than the boxed type (e.g. Boolean.class) even though when get/setValue(...) is inoked the boxed type will be returned. By using the primitive the observable will be able to convey that the value cannot be null. This allows for better control in the validation and conversion phases of binding.

Back to the top