Rice University - Comp 212 - Intermediate Programming

Spring 2007

Lecture #17 -  Simple Java Drawing


 

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 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.
 */
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 at rice.edu
Copyright 2003, Dung X. Nguyen - All rights reserved.