Rice University - Comp 212 - Intermediate Programming

Fall 2003

Lab #7 -  Simple Java Drawing

This is a continuation of the Hangman Project.

This lab's exercises are on creating the GUI for the project and can be found here.

Be sure to check out the note on how to signal the end of the game.


 

1.  Simple Hangman Drawing

Click here to run simple hangman drawing applet.

Here is the HTML code for the applet:

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

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 paint() 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 gc The IGameControlAdapter object used to for guessing and
     * resetting.
     * @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 HangmanFrame (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 adapters.
 * The adapters are implemented as anonymous inner classes.
 */
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();
    }

}


 


dxnguyen@cs.rice.edu
Copyright 2003, Dung X. Nguyen - All rights reserved.