CS 124, Spring 2014
Lab 12: Hangman GUI

For the remainder of the semester, you will work on a final project. The project should be either a Hangman game or another program of similar complexity. Hangman is discussed on this page. If you want to work on a different program, you should discuss your idea with me and get approval for your idea.

You should plan to finish your project by the last day of classes, Tuesday, May 6. However, you can submit your the final version of your program any time up to Monday, May 12, the day after the final exam. To ensure that I can find your work, you should put it in a folder named lab12 in your homework folder in /classes/cs124/homework.

You should work on this project entirely on your own, except possibly for help from the professor. Do not get help from the Internet, from friends, or from other people in the course. TAs have been instructed to give you help with Java and with debugging, but not to give significant help on designing and writing the program.

About Hangman

Hangman is a simple word-guessing game. A version was demonstrated in class. The program selects a word for the user to guess. Initially, each letter in the word is shown as an empty space. The user guesses letters. When the user guesses a letter that appears in the word, that letter is filled in; it is filled in at every space where it occurs in the word, not just one space. When the user guesses a letter that is not in the word, a part of a "hanged man" is drawn. If the hanged man is completed before the user finds all the letters in the word, the user loses. The picture at the right shows an example. The hanged man here is complete. In my version of the game, I start with the scaffold already drawn, and the user gets 7 incorrect guesses. For the first incorrect guess, I draw the man's head; for the second, the neck; and then the left arm, right arm, body, left leg, and right leg.

About Layout, Etc.

You will have to design a user interface for Hangman (or whatever program you write). The game will require 26 buttons, one for each letter of the alphabet, as well as a display panel where you can draw the hanged man. You will also need other components or a menu bar or both. You will need to "lay out" all these components in a main panel. Many of the techniques that you need were covered in the GUI Tutorial, Lab 10. Note in particular that that lab shows how to use a display panel for drawing and a subpanel for holding some buttons, all in a main panel that uses a BorderLayout. You should review Lab 10 and possibly even reuse some of the code from it. We will also talk about layout in class, and you can read about it in Section 6.7. But here are a few things you might use in this program.

To hold the 26 alphabet buttons, you will probably want to put them into a JPanel on which you are using a GridLayout. In a GridLayout, components appear in equal-sized rectangles arranged into rows and columns. To create a panel and install a GridLayout for it, you can say:

JPanel panel = new JPanel();
panel.setLayout( new GridLayout( r, c ) );

where r is the number of rows and c is the number of columns. For example, depending on the overall design of your window, you might arrange 26 buttons into a 2-by-13, or a 3-by-9, or a 9-by-3 grid:

The 3-by-9 and 9-by-3 grids have an empty spot. You are not required to fill the grid completely. Once you have the panel that holds the buttons, you need to add it to your main panel. Presumably, the main panel will use a BorderLayout, like the one in Lab 10. However, it's nice to have a constrasting color between and around the components in a BorderLayout. A BorderLayout can specify a gap between components; the background color of the panel will show through the gaps. To get color around the outside of the panel, you can add a "border." Here's an example of setting this up in the constructor of the main panel:

setLayout( new BorderLayout(3,3) ); // Allow 3-pixel gap between components.
Color darkred = new Color(100,0,0);
setBackground( darkred ); // Color shows between components in the BorderLayout.
setBorder(BorderFactory.createLineBorder( darkred, 3 )); // Shows around edges.

In addition to layout, you might need a few new facts about components. You will at least need to know how to enable and disable buttons. You can read about basic properties of components in the first part of Section 6.6, and you can learn more about buttons in Subsection 6.6.1. You might want to use a JLabel or two to display information to the user. Read about JLabel in Subsection 6.6.2. You will probably want to use bigger fonts than the default for some of your components. You can review basic use of fonts in Subsection 6.3.3.

Finally, you might want to use some of the capabilities of Graphics2D in your drawing. Graphics2D provides extra capabilities that are not available through a standard Graphics object. In fact, the Graphics object in paintComponent is a Graphics2D, and you can type-cast it to get access to the extra methods from Graphics2D. I found it useful to use a wider stroke for drawing and to turn on "antialiasing," which can make lines and ovals look smoother. To do this, add the following lines to paintComponent:

Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3));  // draw 3-pixel-wide lines.
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                              RenderingHints.VALUE_ANTIALIAS_ON);

The Assignment for Lab 12

The assignment for this week is to create the GUI for your program and test that it is working correctly. Next week, you will implement the actual logic of the game.

For your Hangman game, you are required to have 26 buttons representing the letters of the alphabet. The user will select a letter by clicking one of the buttons. Furthermore, you must disable the button when the user clicks it, so that they can't choose the same letter again. After the user finishes with one word, the user must be able to begin a new game with a new word. At that time, all the letter buttons will have to be enabled again—this means that you will want to keep references to the alphabet buttons in an array. You are required to draw the hanged man, step-by-step, as the user makes incorrect guesses. You are required to display information about the progress of the game. You should show all the the guessed letters in the word, with some indication of the blank spaces that have not yet been guessed. And you are required to have extra buttons and/or menu items to provide some features beyond the minimum requirements.

For this week: You should set up the user interface, with all the panels, buttons, etc., that you anticipate using. You should create an ActionListener to respond to buttons and possibly menu commands. For now, it can just print a message to show that the button is functional. You might want to implement the disabling of the alphabet buttons when they are clicked, and you might want to start writing a newGame method that will, among other things, re-enable all the alphabet buttons. You will want to make sure that you can draw the hanged man for all stages of the game. Remember that what you draw will depend on the number of incorrect guesses; you don't have to fully implement the game to test this functionality. You should decide how you want to display the word to the user, and you should test your design; the basic options are to show the word in a JLabel or to draw the characters of the word in the display's paintComponent method. You should also think about what other information you want to display to the user about the progress of the game.

Although you are not required to do so at this time, you can get started on selecting words for the game by including the package words from /classes/cs124/lab12-files. (Copy the entire words folder into your src folder, and add the directive import words.WordList; to the top of your program.) The package includes a class WordList that represents a list of words read from a resource file. The name of the resource file is specified in the constructor. To use it, create an object of type WordList with

wordlist = new WordList("words/wordlist.txt");

and get a randomly selected word from the list by calling wordlist.getRandomWord(). See the comments in WordList.java for more information. The file wordlist.txt contains 425 words. They are a random selection from a much longer list, which is in the file /classes/cs124/wordlist-full.txt; you can add that file to the words folder in Eclipse if you want to use it in your program. You might want to provide your own lists of words. You might even provide several alternative lists of words for the user to choose from.

Other Programs

You have the option of writing a different program for your final project. As I announced in an email, you also have the option of writing an extra program to replace the grade for a previous lab. You might have some ideas of your own for these projects, but here are a few ideas that you can consider. Some are based on previous labs. A couple are labs from previous versions of this course.