/* * StopWatch2.java * Model contains the data and the state for the stopwatch * Created on December 7, 2001, 8:29 AM * * @author Stuart Hansen * @version */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.beans.*; import Views.*; public class StopWatch2 extends JFrame { private long currentTime; // the current time private Timer timer; // the timer goes off every 1/10 seconds (or so) private State state; // the state keeps track of whether the stopwatch is running private JButton startStop; // the start stop button private JButton reset; // reset the stopwatch to 0 /** the constructor */ public StopWatch2() { super ("StopWatch"); // Set up the startStop button startStop = new JButton("Start/Stop"); startStop.addActionListener(new startStopController()); // Set up the reset button reset = new JButton("Reset"); reset.addActionListener(new resetController()); // Add the buttons to the container Container c = getContentPane(); c.setLayout(new FlowLayout()); c.add(startStop); c.add(reset); // setup the current time variables currentTime = 0; // Set up the timer timer = new Timer(67, new TimerHandler ()); state = new Stopped(); timer.setRepeats(true); timer.start(); // Set a few window properties and open the window setSize(300, 50); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } // getters and setters for the time variables public long getCurrentTime () { return currentTime; } // When we set the time, we fire off an event public void setCurrentTime (long timeArg) { long temp = getCurrentTime(); currentTime = timeArg; firePropertyChange("currentTime", new Long(temp), new Long(currentTime)); } // addView sets up a new viewer for the stopWatch public void addView (SWView view) { addPropertyChangeListener(view); view.addPropertyChangeListener(new TimeRequestController()); } // TimeHandler updates handles the timer going off class TimerHandler implements ActionListener { public void actionPerformed (ActionEvent e) { state.updateTime(); } } // State is the state of the data model private interface State { // Responds to the timer events public void updateTime(); // Responds to startStop button public void startStopPushed(); // Responds to the reset button public void resetPushed(); } // Stopped and Started are states for the model // A stopped watch is not running private class Stopped implements State { // We disable reset while the watch is running // We re-enable it when the watch stops public Stopped () { reset.setEnabled(true); } // When the watch is stopped, we don't update the time public void updateTime () { } // The startStop button starts the watch public void startStopPushed() { state = new Started(); } // The reset button sets the time to 0 public void resetPushed() { setCurrentTime(0); } } // A started watch is running private class Started implements State { // Reset is disabled while the watch is running public Started() { reset.setEnabled(false); } // We update the current time variable with each timer event public void updateTime () { setCurrentTime(getCurrentTime()+1); } // startStop stops the watch public void startStopPushed() { state = new Stopped(); } // We do not reset the time while the watch is running public void resetPushed() { } } // startStopController sits between the button and the model public class startStopController extends AbstractAction { public void actionPerformed (ActionEvent e) { state.startStopPushed(); } } // resetController sits between the button and the model public class resetController extends AbstractAction { public void actionPerformed (ActionEvent e) { state.resetPushed(); } } // This class listens for requests for the current time public class TimeRequestController implements PropertyChangeListener { public void propertyChange (PropertyChangeEvent evt) { firePropertyChange("currentTime", null, new Long(currentTime)); } } }