Rice University - Comp 212 - Intermediate Programming

Fall 2002

Lecture #19 - Model-View-Controller


 Click to run Click Counter Applet
 
 
Model-View-Controller Design for Click Counting Program  
 
ClickCounter.java
package click.model;

/**
 * The model that knows how to count.
 */
public class ClickCounter {

    private static final int MAXIMUM = 9;
    private static final int MINIMUM = 0;
    private static final int STRING_WIDTH = 3;  // Maximum number of low-order digits.

    private int count = MINIMUM;
    private ICounter2World _count2World;

    public ClickCounter(ICounter2World c2w) {
        _count2World = c2w;
    }

    public final boolean isAtMinimum() { return count == MINIMUM; }
    public final boolean isAtMaximum() { return count == MAXIMUM; }

    public int inc() {
        if (isAtMaximum()) {
             _count2World.maxOut();
             return count;
        }
        count++;
        if (isAtMaximum()) {
             _count2World.maxOut();
        }
        else {
            _count2World.inRange();
        }
        return count;
    }

    public int dec() {
        if (isAtMinimum()) {
             _count2World.minOut();
             return count;
        }
        count--;
        if (isAtMinimum()) {
             _count2World.minOut();
        }
        else {
            _count2World.inRange();
        }
        return count;
    }

    public void reset() {
        count = MINIMUM;
        _count2World.minOut();
    }

    public int getCount() {
        return count;
    }

    /**
    * Returns low-order digits of decimal representation of counter value.
    * STRING_WIDTH specifies the number of digits
    */
    public String toString() {
    StringBuffer buffer =  new StringBuffer(Integer.toString(count));
    // buffer now contains the String representation of count.
    while (buffer.length() < STRING_WIDTH) {
        buffer.insert(0,0);
        // each insert increases the buffer length by 1 and scoots the buffer
        // content to the right by 1.
    }
    return buffer.toString();
    }
}

ICounter2World.java
package click.model;

/**
 * Adapter for Counter to talk to the outside world.
 */
public abstract interface ICounter2World {
    public abstract Object maxOut();
    public abstract Object minOut();
    public abstract Object inRange();
}

ClickCounterView.java
Created with JBuilder
package click.view;

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

public class ClickCounterView {

    private JButton incButton;
    private JButton resetButton;
    private JButton decButton;
    private JLabel valueDisplay;
    private IView2World _view2World;

    public ClickCounterView(JApplet itsApplet, IView2World v2w) {
        _view2World = v2w;
        JPanel controlPanel = new JPanel();

        itsApplet.getContentPane().setLayout(new BorderLayout());
        valueDisplay = new JLabel("000", JLabel.CENTER);

        itsApplet.getContentPane().add(valueDisplay, "Center");

        incButton = new JButton("+");
        incButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _view2World.incClicked(e);
            }
        });

        resetButton = new JButton("Reset");
        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _view2World.resetClicked(e);
            }
        });

        decButton = new JButton("-");
        decButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _view2World.decClicked(e);
            }
        });

        controlPanel.add(incButton);
        controlPanel.add(resetButton);
        controlPanel.add(decButton);
        itsApplet.getContentPane().add(controlPanel, "South");

        setMinimumState();
        setValueDisplay("");
    }

    public void setValueDisplay(String setTo) {
        valueDisplay.setText(setTo);
    }

    public void setMinimumState() {
        incButton.setEnabled(true);
        resetButton.setEnabled(false);
        decButton.setEnabled(false);
    }

    public void setCountingState() {
        incButton.setEnabled(true);
        resetButton.setEnabled(true);
        decButton.setEnabled(true);
    }

    public void setMaximumState() {
        incButton.setEnabled(false);
        resetButton.setEnabled(true);
        decButton.setEnabled(true);
    }
}

IView2World.java
package click.view;

import java.awt.event.*;

/**
 * Adapter connecting the View to the outside world.
 */
public interface IView2World {
    public Object incClicked(ActionEvent e);
    public Object decClicked(ActionEvent e);
    public Object resetClicked(ActionEvent e);
}

ClickCounterControl.java
package click.controller;

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

import click.model.*;
import click.view.*;
import view.AFrame;

/**
 * Installs the concrete adapters to wire the counter model and the counter view
 * together.
 */
public class ClickCounterControl extends JApplet {

    private ClickCounter counter;
    private ClickCounterView view;

    /**
     * All applet must have an init() method.
     */
    public void init() {
        counter = new ClickCounter(new ICounter2World() {
            public Object maxOut() {
                view.setMaximumState();
                return null;
            }

            public Object minOut() {
                view.setMinimumState();
                return null;
            }

            public Object inRange() {
                view.setCountingState();
                return null;
            }
        });

        view = new ClickCounterView(this, new IView2World() {

            public Object incClicked(ActionEvent e) {
                counter.inc();
                view.setValueDisplay(counter.toString());
                return null;
            }

            public Object decClicked(ActionEvent e) {
                counter.dec();
                view.setValueDisplay(counter.toString());
                return null;
            }

            public Object resetClicked(ActionEvent e) {
                counter.reset();
                view.setValueDisplay(counter.toString());
                return null;
            }
        });
        view.setValueDisplay(counter.toString());
    }

    public static void main(String[] args) {
        JFrame frame = new AFrame("Click Counter Application") {
            protected void initialize() {
                ClickCounterControl controller = new ClickCounterControl();
                controller.init();
                getContentPane().add(controller, "Center");
                setSize(400, 400);
                setVisible(true);
            }
        };

    }
}