[Texas PLT logo]

COMP 202: Principles of Object-Oriented Programming II

  Lab 02  

Introduction

This tutorial covers:


1. UML Sequence Diagram

The UML class diagrams for the design of Hangman can only describe the static relationships between the various classes.  To illustrate the dynamic interactions between the various objects in the system at runtime, we use UML sequence diagrams.  Below are UML sequence diagrams depicting different scenarios in playing the game.

a. Correctly guess a character but still need to continue playing

b. Correctly guess a character and win

c. Incorrectly guess a character but still need to continue playing

d. Painting the body parts

 

e. The game is lost when the noose is drawn 


2. Simple Hangman Drawing

Below is the complete code for a Java Applet that does some simple drawing.

A Java applet is a Java program that resides on some Web server and can be downloaded to the local machine by the browser and run on the local machine within the confine of the browser.   See the short discussion on applets below.

Click here to run simple hangman drawing applet.

Here is the HTML code for WEB page that calls the applet HangmanController:

<HTML>
<HEAD>
<TITLE> Drawing Hamgan</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>
Simple Drawing of Hangman
</H1>
<P>
<HR>
<APPLET CODEBASE="classes" CODE="controller.HangmanController.class"  WIDTH = 400 HEIGHT = 350>
</APPLET>
<HR>
<P>
</CENTER>
</BODY>
</HTML>

The optional CODEBASE parameter is used here because the directory structure we use with DrJava places the default package directory for the compiled classes in the "classes" (build) directory.   The above HTML file is assumed to be in the same directory as the DrJava project, i.e. just above the "src" and "classes" directories.

Click here for all the source code.

The Model

HangmanGame.java 
package model;

import java.awt.*;

import model.bodyPart.*;

/**
 * This simplified version of the model has no adapters to play the game.
 * There is no game to play here.  Just a few ABodyPart to display via the
 * paint() method.
 * The IPaintAdapter installed by the controller will call the HangmanGame to
 * paint(...).
 */
public class HangmanGame {
    /**
     * A few ABodyPart to be drawn.
     */
    private ABodyPart _noose = new NoosePart(null, null);
    private ABodyPart _rightArm = new RArmPart(null);
    private ABodyPart _torso = new TorsoPart(null);

    /**
     * Paints the visible body parts on the supplied Graphics context.
     * @param g The Graphics context to draw on.
     */
    public void paint(Graphics g) {
        // FOR ILLUSTRATION ONLY:
        System.out.println("HangmanGame.paint()...");

        _noose.draw(g);
        _rightArm.draw(g);
        _torso.draw(g);
    }
}

The View

HangmanGUI.java 
package view;

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

/**
 * Serves as a view to Hangman.
 * Has a JPanel where the body parts are painted.
 * Uses a JApplet to supply the Graphics context for the JPamel to draw the body
 * parts.
 * To paint something in Java, we need to paint on a JPanel and override
 * its paintComponent(...) method.
 * Everytime the JPanel needs repainting, it will call paintComponent(...).
 * For example, when the JFrame or a JApplet that contains the JPanel is
 * resized, it will try to update all of its contents, in particular it will
 * call its JPanel to update, which in turns will schedule a call to
 * repaint(...), which in turn will call paintComponent(...)!
 */
public class HangmanGUI {

    /**
     * The GUI component that holds all other GUI components.
     */
    private JApplet _applet;

    /**
     * The adapter used to communicate with the model to tell it to paint the
     * body parts.
     */
    private IPaintAdapter _paintAdapter;

    /**
     * A panel derived from a JPanel where the body parts are drawn.
     * The JPanel's paintComponent() method is overriden so that the gallows is
     * automatically drawn when the panel is repainted.
     */
    private JPanel _displayPanel = new JPanel() {
        public void paintComponent(Graphics g) { // called whenever the panel is
            // repainted.  The graphics context g is supplied by the GUI
            // component that contains this JPanel.
            super.paintComponent(g);   // do whatever usually is done,
                // e.g. clear the panel.
            g.setColor(Color.black);  // set the drawing color
            g.fillRect(0,220,200,5);  // base of scaffold
            g.fillRect(0,0,70,5);     // top of scaffold
            g.fillRect(0,0,5,220);    // side of scaffold

            // FOR ILLUSTRATION ONLY:
            System.out.println("HangmanGUI._displayPanel.paintComponent() " +
                "calling _paintAdapter.paint()...");

            //  Delegate to the adapter to get the body parts drawn:
            _paintAdapter.paint(g);
        }
    };


    /**
     * Initializes the GUI components.
     * @param a the applet that holds all GUI components.
     * @param pa The IPaintAdapter object used for requesting that the model
     * paint the body parts.
     */
    public HangmanGUI(JApplet a, IPaintAdapter pa) {
        if (null == a || null == pa) {
            throw new IllegalArgumentException("HangmanGUI(...) has null " +
                "arguments!");
        }
        // FOR ILLUSTRATION ONLY:
        System.out.println("HangmanGUI.constructor initializing _displayPanel "
            + "and _applet...");

        _applet = a;
        _paintAdapter = pa;
        guiInit();
    }

    /**Component initialization*/
    private void guiInit() {
        _displayPanel.setBackground(Color.white);
        _applet.setSize(400, 350);
        Container contentPane = _applet.getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(_displayPanel, BorderLayout.CENTER);
    }
}

IPaintAdapter.java 
package view;

import java.awt.*;

/**
 * Adapter used by the HangmanGUI (view) to get the HangmanGame (model)
 * to paint the body parts onto the supplied Graphics context.
 */
public interface IPaintAdapter {
    /**
     * Paints the body parts onto a given Graphics context.
     * @param g The Graphics context to paint on.
     */
    public abstract void paint(Graphics g);
}

The Controller

HangmanController.java
package controller;

import model.*;
import view.*;
import javax.swing.*;
import java.awt.*;

/**
 * The controller implemented as a JApplet to instantiate and connect the
 * HangmanGame (the model) and the HangmanGUI (the view) via adapters.
 * The controller also instantiates the adapter(s).
 * The adapter(s) is(are) implemented as anonymous inner class(es) to take advantage
 * of closure.
 * This applet can also run as a regular Java application (see main() method).
 */
public class HangmanController extends JApplet{

    private HangmanGUI _gui;
    private HangmanGame _hangman;

    /**
     * Instantiates the HangmanGame, HangmanFrame, and connects them together
     * using anonymous inner class IPaintAdapter.
     * In this simplified version, there is no game playing, so there is no
     * need for loose and/or win adapters.
     */
    public void init() {
        _hangman = new HangmanGame();
        _gui = new HangmanGUI(this, new IPaintAdapter()  {
            public void paint(Graphics g) {
                // FOR ILLUSTRATION ONLY:
                System.out.println("anonymous IPaintAdapter.paint() calling " +
                    "_hangman.paint()...");

                _hangman.paint(g);
            }
        });
    }

    /**
     * Runs as a stand-alone GUI application with a main frame that contains
     * a HangmanController JApplet.
     * @param nu not used.
     */
    public static void main(String[] nu) {
        JFrame frame = new AFrame("Simple Hangman Drawing") {
            protected void initialize() {
                HangmanController controller = new HangmanController();
                controller.init();
                getContentPane().add(controller, "Center");
                setSize(400, 400);
                setVisible(true);
            }
        };
        frame.validate();
    }

}

3. Java Applets in a (Very Small) Nutshell

Java applets are essentially Java applications that are meant to be run in a client's web browser.   Because applets are downloaded from a (usually remote) web server to the client's computer, there are some very strong restrictions placed on what an applet is allowed to do.     We say that the applet is allowed to run inside of a security "sandbox".   For instance, an applet is not allowed to read or write to the client's disk or to make network connections to anything but the host server from which it came.  

A web page can invoke an applet to run inside that web page by imbedding the special <APPLET> HTML tag in the following manner:

<APPLET CODEBASE="default_package_location" CODE="fully_qualified_classname.class"  WIDTH = w HEIGHT = h>
</APPLET>

 

where fully_qualified_classname.class is the name of the class to run (including the .class extension), including any package name and where the default package directory is the directory the calling web page is located.   "w" and "h" are optional parameters that determine the width and height of the applet in the browser in pixels.

The optional CODEBASE parameter allows us to specify a directory other than the directory the HTML file is located to be the default package directory for the compiled Java code.   In general, "default_package_location" would be relative to the directory the HTML file is in.

An applet must extend the Java Swing component JApplet in order to gain the necessary functionality. There are several methods that an applet can have to control the way that the browser starts it and stops the applet.   The most important of these is the init() method. 

public class MyApplet extends JApplet{

     public void init() { ...}

}

 The init() method is run when the web page containing the applet is first loaded.   It is only run once.  That is if the page is minimized and resized, it is not run again.   It will be run again if the user browses off the page and then returns.   This method is used to initialize the applet and get it ready to run.  This method often instantiates and initializes any GUI components.  In Hangman, it is the running of the controller code to build and connect the model and the view.

There are other methods, such as public void start() and public void stop() that are called each time the page is displayed to start and stop the applet, but these methods are not as commonly used.

 


4. Hangman Project Part 2

Programming project #1 asks you to write a GUI program to play hangman.  The GUI is the "view" with respect to the "model" you created last week. The tutorial found at the View and Controller page will take you step by step through creating the GUI needed for your project. While you are not required to have exactly the GUI you create in the tutorial, your project must have at least its level of functionality. We strongly recommend that you follow the instructions and create the GUI as described before you attempt to customize it.

Technically, the lab tutorial only consists of the "View" section in the above mentioned web page.  By completing the exercises in the above link, you will have completed another non-trivial part of the programming project.

You are free to collaborate with other lab partners in the lab and share the code written during this lab only.  Afterwards, you will have  to work alone on the project.  Your labbies will give you guidance but will not help you write the code.   


Last Revised Monday, 25-Jan-2010 17:14:03 EST

©2007 Stephen Wong and Dung Nguyen

  Lab 02  

URL: http://www.cs.rice.edu/teaching/202/08-fall/labs/hangman2/index.shtml
Copyright © 2008-2010 Mathias Ricken and Stephen Wong