Wednesday, August 31, 2011

Notifier Design Pattern

Say you want to develop an application which will have many viewers/pages and all these have to be refreshed with the latest data as soon as the data changes in the engine.

A very simple example is - Weather Reports. When the data changes in the engine, the weather report page has to be refreshed to show the latest data.

Let's follow the below steps:
  1. Develop your report dialog - which will show the weather information.
  2. Implement the ChangeListener in the dialog report- This will act as a listener
  3. Implement your report data class, which contains the weather information. This will act a notifier and also as a registry.
  4. Register your listener with the data class so that the viewer will get a notification if the data changes.

Here is the sample code for it:

import java.util.List;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
 * Weather report dialog.
public class WeatherDetailsDialog implements ChangeListener {
 private TableViewer weatherViewer;
 protected WeatherDetailsDialog() {  
  //your specific data passed through constructor 
 protected void createReport(Composite topComposite) {
  Group dependantsViewerGroup = new Group(topComposite, SWT.NONE);
  dependantsViewerGroup.setLayout(new GridLayout());
  GridData gridData3 = new GridData(SWT.FILL, SWT.FILL, true, false);
  dependantsViewerGroup.setText("Weather Report"); //$NON-NLS-1$
  weatherViewer = new TableViewer(
    dependantsViewerGroup, SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.BORDER);
  final Table reportTable = weatherViewer.getTable();
  GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
  gridData.heightHint = 140;
  TableColumn cityName = new TableColumn(reportTable, SWT.LEFT);
  cityName.setText("City"); //$NON-NLS-1$
  TableColumn valueColumn = new TableColumn(reportTable, SWT.LEFT);
  valueColumn.setText("Value"); //$NON-NLS-1$
  TableColumn descriptionColumn = new TableColumn(reportTable, SWT.LEFT);
  descriptionColumn.setText("Description"); //$NON-NLS-1$
  weatherViewer.setContentProvider(new WeatherContentProvider()); 
  weatherViewer.setLabelProvider(new WeatherLabelProvider());
  //Register viewer with the weathe report data.
  List<IWeather> reportData = computingEngine.getReportData();
  for (IWeather data : reportData) {
     * Invoked when the target of the listener has changed its state.
     * @param e  a ChangeEvent object
 public void stateChanged(ChangeEvent arg0) {
  Display.getDefault().asyncExec(new Runnable() {
   public void run() {

This will notfiy as soon the data changes.

import java.util.ArrayList;
import java.util.List;
import javax.swing.event.ChangeListener;

public class Weather {

 private List<ChangeListener> registeredListners = new ArrayList<ChangeListener>();
 private ComputingEngine ComputingData;
 private Float newValue;
 private String description;
 public Weather(ComputingEngine ComputingData) {
  this.ComputingData = ComputingData;
  * Updating the status change. This will notify to all the registered listeners
  * Ex: It will notify to the viewer/UI about the weather change report
  *   */
 public void setValue(Float newValue) {
  this.newValue = newValue;
 public ComputingEngine getComputingData() {
  return ComputingData;
 public void setDescription(String description) {
  this.description = description;
 public String getDescription() {
  return description;
 public Float getNewValue() {
  return newValue;
 //Add your listener here
 public void addChangeListener(ChangeListener listener) {
  if (!registeredListners.contains(listener))
 //removing the listener
 public void removeChangeListener(ChangeListener listener) {
  if (registeredListners.contains(listener))
 //This will be triggered when the state changes
 public void notifyListeners() {
  for (ChangeListener listener : registeredListners) {

No comments:

Post a Comment