Lab 15: GUI Part I

The goal of this lab is to practice using Java's GUI capabilities to write programs that use windows and buttons.

I. Example programs

We'll start by looking at some example programs, including the two that were in the handout.

1. Set-up

Clone the repository from the class public directory and move into the examples subdirectory:

hg clone /cslab/class/csci235/lab15
cd lab15/examples

2. Example1

Start by looking at Example1.java. This program simply puts up a window (JFrame that contains two instances of JLabel. There are two statements that configure the window, setting its size and initial location on the screen; the unit of measurement is the pixel, short for picture element, which is the smallest dot the screen displays. Throughout the GUI libraries, dimensions and coordinates are specifies as row, column, with row zero at the top of the screen and column zero at the left edge.

The other bit of configuration to notice is the call to setDefaultCloseOperation(). This tells the program to exit when you close this window.

Compile and run this program:

javac Example1.java
java Example1
Notice that the program does not exit when it reaches the end of the main() method. Instead, the program stays around waiting for events. To quit the program, close the window by clicking on the "X" decoration at the upper left.

Modify Example1.java, changing the size of the window to be wider than it is tall, and to move its starting location lower on the screen. Compile and run it with your changes.

Note that you can resize the window while the program is running, by "grabbing" an edge or corner with the mouse and dragging it. Notice how the grid layout tries to adapt as you change the shape and size of the window.

Modify the program again, replacing the GridLayout(2, 1) with a FlowLayout(). Compile and run the new version, and compare how the layout adjusts to changes in the window size and shape.

3. Action!

Now take a look at Example2.java, which is almost the same as the earlier program, but replaces the second JLabel with a JButton. The button can produce an event when it is clicked; so this version of the program calls the button's addActionListener() method to specify the listener object that should be called when the event fires.

Look at OkListener2.java. Notice that this class implements the ActionListener interface, which requires it to provide a method actionPerformed().

Compile and run Example2. You can try resizing this one as you did for the previous program. What do you expect to happen when you click on the button? Give it a try.

Now modify Example2.java by commenting out the first call to addActionListener() and uncommenting the second. Before you compile and run the program, see if you can predict what will happen. Give it a try. Peek here if you need help figuring out how to get back.

Now it is time to try a more interesting program.

II. The Fifteen Puzzle

1. Introduction

A Fifteen Puzzle (or, more generally, an N-puzzle) consists in a grid of square, same-sized tiles, with all but one of the grid positions filled. The object of the game is to rearrange the tiles by sliding the tiles one at a time until a certain configuration is reached (for example, starting from a random configuration until the numbers are in order).

In this lab, you will write a program that simulates a Fifteen Puzzle

2. Set-up

Change into this lab's other subdirectory, with

cd ../puzzle

Open FifteenPuzzle.java in xemacs and read through it. Notice that it basically adds sixteen buttons to the window. Compile and run, and notice that the buttons are put right on top of each other, and all of the buttons contain a number in the range 0 to 15.

3. Adjusting the window

Based on what you've seen so far, play around with the size, location, and layout management until you can see that you have sixteen buttons arranged in a square.

4. Making the puzzle work

Each button stands for a tile or block in the puzzle. 15 of them will have numbers, and the 16th will be blank. We won't actually move the buttons around; instead, we will change the numbers on the buttons to give the appearance of moving tiles.

When a button is clicked, the following should happen:

Each button needs to have an action listener to perform this. Uncomment the relevant sections in FifteenPuzzle.java. We are using an action listener class called PuzzlePiece. The skeleton of this class is given to you. You'll need to supply the methods to complete it, but be sure that you read the rest of this section before you start trying to write code. The methods needed are:

Hint: Notice again that when a button is clicked, its action listener must communicate with the action listeners on the neighboring buttons---first, to determine if one of the neighbors is blank; second, to make any necessary changes. How can you do this? You may want to write a few extra methods in the class PuzzlePiece.

You will need to make a few changes to the main() method in FifteenPuzzle.java. First, you should uncomment the two sections of code that are marked. You will also need to change the JButton constructor call (or add something else) so that the last button (number 0) is initially blank.

5. Turn in

Turn in your .java source files from the puzzle directory with the command

/cslab/class/csci235/bin/handin lab15 PuzzlePiece.java FifteenPuzzle.java

Be sure to include all of your files on a single command.


Hint: When the Example2 window disappears, the program is still running, but you no longer have a way to interact with it. You can kill it by typing a control-C in the terminal window from which you ran it.

Click here to jump back to where you were in the lab.


Thomas VanDrunen, Cary Gray
Last modified: Thu Apr 12 17:36:25 CDT 2012