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); } }