Example of Animated Applet with GUI Controls
Fall 2002, David Matuszek

The following is a very simple example of an applet that (1) does animation, (2) can be controlled by the GUI, and (3) uses the Model-View-Controller and Observer/Observable design patterns. Some of the more important lines are highlighted in red. This code, along with the MessageWindow code, is available as a zip file.

Controller.java
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Controller extends Applet {
    Panel buttonPanel = new Panel();
    Button runButton = new Button("Run");
    Button stopButton = new Button("Stop");
        
    Model model = new Model();
    View view = new View(model);
    
    public void init() {
      // Lay out components
      setLayout(new BorderLayout());
      this.add(BorderLayout.SOUTH, buttonPanel);
          buttonPanel.add(runButton);
          buttonPanel.add(stopButton);
          stopButton.setEnabled(false);
      this.add(BorderLayout.CENTER, view);
      
      // Attach actions to components
      runButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent event) {
            model.okToRun = true;
            Thread modelThread = new Thread(model);
            modelThread.start();
            runButton.setEnabled(false);
            stopButton.setEnabled(true);
         }
      });
      stopButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent event) {
            model.okToRun = false;
            runButton.setEnabled(true);
            stopButton.setEnabled(false);
         }
      });
      
      // Connect model and view
      model.addObserver(view);
   }
    
    public void start() {
        // Tell model how big its window is
        model.xLimit = view.getSize().width - model.BALL_SIZE;
        model.yLimit = view.getSize().height - model.BALL_SIZE;
    }
}

Model.java
import java.util.Observable;

class Model extends Observable implements Runnable {
    public boolean okToRun = false;
    final int BALL_SIZE = 20;
    int xPosition = 0;
    int yPosition = 0;
    int xLimit, yLimit;
    int xDelta = 6;
    int yDelta = 4;
    
    public void run() {
        while (okToRun) {
            // Do the work
            xPosition += xDelta;
            if(xPosition < 0 || xPosition >= xLimit) {
                xDelta = -xDelta;
                xPosition += xDelta;
            }
            yPosition += yDelta;
            if(yPosition < 0 || yPosition >= yLimit) {
                yDelta = -yDelta;
                yPosition += yDelta;
            }
            // Notify observers
            setChanged();
            notifyObservers();
            // Pause for 1/20 second
            try { Thread.sleep(50); }
            catch (InterruptedException e) {}
        }
    }
}

View.java
import java.awt.*;
import java.util.*;

class View extends Canvas implements Observer {
    Model model;

    // Constructor
    View(Model model) {
        this.model = model;
    }
    
    public void paint(Graphics g) {
        g.setColor(Color.red);
        g.fillOval(model.xPosition, model.yPosition,
                   model.BALL_SIZE, model.BALL_SIZE);
    }
    
    public void update(Observable obs, Object arg) {
        repaint();
    }
}