Java Quiz Player

Java Swing Example using Observer and Observable

Jul 23, 2013

This blog post is about using Java Observable class and Observer interface using a Swing GUI based example. This post includes notes on the related Model View and Observer design principles.

The Observer and Observable are defined in Java SE's java.util package. These API is used to implement an example application.

1. The Example

The example is a Java Swing application. This has two GUI windows, an Observable data class and a starter program.

1.1. Main Window

This window displays a text message, whenever data is changed in an Observable object. This is a Observer object. This implements the Observer interface and its update() method.

1.2. Dialog Window

This window has a button, and when clicked (action) updates (data in) an Observable object. The class creates an Observable object and adds (or registers) the Main Window as an Observer (to the Observable).

1.3. Message Observable

This class extends Observable; has a method to notify (or inform) of (the data) changes in this.The Observer object (Main Window) is informed of any changes to this.

1.4. Example Application Starter

This class starts the application; displays the two GUI windows. Close the Main Window to exit the application.

1.5. The Example Application's GUI

  1. Main Window, at the start of application.
  2. Dialog Window, with the button.
  3. Main Window, after the button is clicked in Dialog Window. Each time the button is clicked, the text with a click counter is displayed in the Main Window.
GUI image 1 GUI image 2 GUI image 3

1.6. Example Application's Code

The example code ExampleAppStarter.java is listed at the end of this post.

2. The API

2.1. Observer Interface

This is informed of changes in a Observable object (and, can receive notifications from multiple Observable objects).

This has only one method, public void update(Observable ob, Object data). The Object argument data can be a null value. The Observable argument ob can be used to identify the type, in case this Observer gets notifications from multiple Observable objects; for example:

if (ob instanceof MessageObservable) {
    // do something
}
else {
    // print error
}

2.2. Observable Class

This represents an Observable object. This class can be subclassed. When an Observable object changes, the notifyObservers() method informs all the Observer objects (which are added to this or registered with this). The Observer object's update() method receives these notifications and optional data.

Useful methods in this class: addObserver(), removeObserver(), notifyObservers(), setChanged() and hasChanged().

An Observable object can have multiple Observer objects registered with it.

3. Design Notes

Observer and Model View Design Principles:

3.1. In the Model-View paradigm:

In the example application, the Message Observable is the data and the Main Window is the view. The Dialog Window is the controller.

3.2. The Observer design pattern:

In the example application, the data is the subject and the display is the Observer. The display receives changes in that data.

3.3. In Java:

The design principles are not only applied for connecting UIs and model objects; in Java Swing the GUI objects like a JButton publish GUI-related events. In an application:

These are two of the listener interfaces:

4. References

Link to Java SE 7 API: http://docs.oracle.com/javase/7/docs/api/index.html?overview-summary.html

5. ExampleAppStarter.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class ExampleAppStarter {
    public static void main(String [] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ExampleAppStarter().start();
            }
        });
    }
    private void start() {
        MainWindow m = new MainWindow();
        new DialogWindow(m);
    }
} // ExampleAppStarter

class MainWindow implements Observer {
    private JLabel label;
    @Override // Observer interface's implemented method
    public void update(Observable o, Object data) {	
        label.setText((String) data); // displays new text in JLabel
    }
    MainWindow() {	
        JFrame frame = new JFrame("Main Window");
        frame.getRootPane().setBorder(
            BorderFactory.createEmptyBorder(20, 20, 20, 20));		
        label = new JLabel("Click button in Dialog...");
        label.setFont(new Font("Dialog", Font.PLAIN, 20));	
        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 150);
        frame.setLocation(200, 200);
        frame.setVisible(true);
    }
} // MainWindow

class DialogWindow {
    private int clicks;
    DialogWindow(MainWindow mainWindow) {
        // Create Observable and add Observer		
        final MessageObservable observable = new MessageObservable();
        observable.addObserver(mainWindow);
        // Display Dialog
        JFrame dialog = new JFrame("Dialog");		
        JButton button = new JButton("Press me");
        button.setFont(new Font("Dialog", Font.PLAIN, 20));
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String data = "button clicked in dialog [" + ++clicks + "]";
                observable.changeData(data);
            }
        });		
        dialog.add(button);
        dialog.setSize(250, 150);
        dialog.setLocation(600, 200);
        dialog.setVisible(true);
    }
} // DialogWindow

class MessageObservable extends Observable {
    MessageObservable() {	
        super();
    }
    void changeData(Object data) {
        setChanged(); // the two methods of Observable class
        notifyObservers(data);
    }
} // MessageObservable

6. Download

Download source code here: SwingObserverExample.zip

Return to top