CSC 8310: Example Applet with GUI
David Matuszek, Villanova University


This applet uses a simple GUI, and exemplifies the Model-View-Controller design pattern. That is, it divides the problem in three parts and assigns behaviors to each, as follows:

This clean separation should make it a lot easier for you to adapt my code to your needs.


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

/**
 * The Controller defines the layout, initializes the Model, and
 * put up the controls (in this case, a single "Step" button).
 * It controls the Model by calling makeOneStep(), and it controls
 * the View by calling view.repaint() as needed.
 */
public class Controller extends Applet {

  // Declare components here, where they are visible to inner classes
  Panel buttonPanel = new Panel ();
  Button stepButton = new Button ("Step");
	
  Model model = new Model ();
  View view = new View ();
	
  /**
   * Creates and lays out components. Also tells the View about
   * the Controller so that it can access the status line.
   */
  public void init () {
	
    // Lay out components
    setLayout (new BorderLayout ());
    buttonPanel.add (stepButton);
    this.add (BorderLayout.SOUTH, buttonPanel);
    this.add (BorderLayout.CENTER, view);
		
    // Attach actions to components
    stepButton.addActionListener (new ActionListener () {
      public void actionPerformed (ActionEvent event) {
        model.makeOneStep ();
        view.repaint ();
    }});
	 
    // Tell the View about myself (Controller) and about the Model
    view.model = model;
    view.controller = this;
  }
	
  /**
   * Records the Applet size. We can't do this in init() because
   * the Applet doesn't actually have a size until it has been
   * initialized.
   */
  public void start () {
    model.xLimit = view.getSize ().width - model.BALL_SIZE;
    model.yLimit = view.getSize ().height - model.BALL_SIZE;
    repaint ();
  }
}



/** The Model is the actual simulation (in this case, of a
 * bouncing ball). The Controller class causes it to do something
 * by calling makeOneStep(). The model class doesn't know or care
 * about either the Controller class or the View class.
 */
class Model {
  final int BALL_SIZE = 20;
  int xPosition = 0;
  int yPosition = 0;
  int xLimit, yLimit;
  int xDelta = 6;
  int yDelta = 4;

  /**
   * Advances the simulation one step.
   */   
  void makeOneStep () {
    xPosition += xDelta;
    if (xPosition < 0) {
      xPosition = 0;
      xDelta = -xDelta;
    }
    if (xPosition >= xLimit) {
      xPosition = xLimit;
      xDelta = -xDelta;
    }
    yPosition += yDelta;
    if (yPosition < 0 || yPosition >= yLimit) {
      yDelta = -yDelta;
      yPosition += yDelta;
    }
  }
}

	

/**
 * The View class is responsible for displaying the current
 * condition of the Model. It is entirely concerned with display,
 * not with running or controlling the simulation. (It does,
 * however, use the showStatus(String) method to put a message
 * in the part of the display owned by the Controller.)
 */
class View extends Canvas {
  Controller controller;
  Model model;
  int stepNumber = 0;
  
  /**
   * Display the current state of the simulation.
   */
  public void paint (Graphics g) {
    g.setColor (Color.red);
    g.fillOval (model.xPosition, model.yPosition,
                model.BALL_SIZE, model.BALL_SIZE);
    controller.showStatus ("Step " + (stepNumber++) +
                           ", x = " + model.xPosition +
                           ", y = " + model.yPosition);
  }
}