Tutorial 6: MVC, Event Handling


Introduction

This tutorial covers:


I. Model-View-Controller

Create a local directory tutorials/06 for this lab and copy the files ~comp212/tutorials/06/hangmanModel/* and ~comp212/tutorials/06/WordTest/*.  These are the Java source code and byte code for a GUI application that can be used to test the classes required for milestone #1 of project #1.  To see how the application behaves, run the command: java WordControl. You should see a window appear.  This window has input/output text field to the north (top), an input textfield to the south (bottom), a reset button to the east (right), and an output label field to the west (left).  This window is called the view.   It is implemented as the class WordGUI.  Now, perform the following actions.

1. Type the word hello in the top text field and hit enter.  The input text becomes _ _ _ _ _ .

2. Type the letter l in the bottom text field and hit enter.  The top text field should display _ _ l l _ , and the output label field should display Good Guess!

3. Erase the letter l in the bottom text field, type the letter a, and hit enter.  The top text field should display _ _ l l _ , and the output label field should display Wrong Guess!

4.Erase the letter a in the bottom text field, type the letter h, and hit enter.   The top text field should display h _ l l _ , and the output label field should display Good Guess!

5. You can finish the game if you wish.

The object that does all the checking of the guesses is called the model.   It is represented by the class AWord together with all of its variants (concrete subclasses) and supporting classes.  When a user types a guess letter in the bottom text field and hits the enter key, the Java virtual machine fires an appropriate event and delivers it to this text field.  This text field is programmed to respond to this event by first inquiring the AWord model to match the guess and then updating the other GUI component accordingly.  The wiring between a GUI component and the model is called a control.  The class WordControl establishes all the controls to wire the GUI view to the AWord model.  The design of this small GUI application is fashioned according what is commonly known as the Model-View-Control (MVC) paradigm.  The UML diagram below illustrates the design.

MVCGUI.png (17164 bytes)

In the above diagram, class WordFactory is nor part of the MVC design.  It is a factory to manufacture concrete instances of AWordWordGUI does not know anything about the model.  It has several GUI components (e.g. JTextFiedl, JButton) and exposes them to the outside world via appropriate getter methods (e.g. get_tfWord, get_resetBtn).   Likewise, AWord, NonEmptyWord, and EmptyWord do not know anything about the view.  They only have the intelligence to match a character and to tell whether or not they are a winner.  WordControl connects the GUI to the model by installing ActionListener objects for each GUI component of the view that needs to respond to an external event.   These ActionListener objects are usually implemented as inner classes in Java.

II. Event Handling

For a GUI component to respond to an event, you must attach to it an appropriate event listener object.  ActionListener is a special kind of event listener that is associated with  GUI components such as JTextField and JButton.  You attach an ActionListener to a GUI component by calling addActionListener (...) on the GUI component.  The following code fragment for the constructor of WordControl illustrates the attachment of event listeners to GUI components.

public WordControl()
{
   // Add controller for hangman word input/output
   _frame.get_tfWordIO().addActionListener (
      new java.awt.event.ActionListener ()
      {
         public void actionPerformed (ActionEvent e)
         {
           _aWord = WordFactory.Singleton.makeWord( _frame.get_tfWordIO().getText());
           _frame.get_tfWordIO().setText(_aWord.toString());
           _frame.get_tfWordIO().setEditable(false);
         }
      }
   );

//...

}

ActionListener is an interface, a special kind of abstract class with no code bodies for the methods and no non-static fields, with one (abstract) method: public void actionPerformed (ActionEvent e).  A concrete ActionListener must have code for this method,as shown in the above code fragment.  This method will be executed when an ActionEvent is fired and delivered to the corresponding GUI component.  In the above example, _frame.get_tfWordIO()is the top text field.  Whenever a text is entered there, the ActionListener object attached to this component will execute its  actionPerformed method. The ActionListener object attached to the top text field is created in a very special way: it does not have a name and exists only in the context of an instance of WordControl!   As constructed, it is called an anonymous inner class of class WordControl.  In the above diagram, the anonymous event listener/handler for the top text field is labeled WordControl$1.   Each inner class object has a reference to its outer object WordControl.

The following is a summary of how to design a GUI application in Java using the MVC paradigm.

1. Design a GUI and expose appropriate GUI components with getter methods (e.g. WordGUI).

The standard approach to build a window is to subclass JFrame.  The labbies will help you complete the construction of the frame

2. Design the model with appropriate intelligence to solve the problem at hand (e.g. AWord and its concrete variants).

You have already implemented AWord and other supporting classes in milestone #1 of the hangman project.

3. Design a controller to instantiate views and  models, and attach event listeners to appropriate GUI components in order to wire the view to the model (e.g. WordControl).

The labbies will help you complete the code for the listener to the bottom text field where your guess is entered.

HAVE FUN!

dxnguyen@cs.rice.edu
revised 10/06/00