Copyright Chris Johnson, 1998.

Human Computer Interface Design Using Java

Exercise 3: Layout Managers,
Event Handlers and Simple Graphics

A. Introduction

This practical introduces a number of features in AWT. The initial tasks focus on the use of different layout managers. Next, you must learn to use some of the AWT graphics routines. The final tasks look at more complex event handlers than we have met up to this point.

You should work in groups of no more than three people for this practical. Please form into teams as quickly as possible because there is a lot of work to cover in this practical. I would expect all groups to complete tasks 1 to 3 before the next practical session. Tasks 4 and 5 reflect a higher level of difficulty but I would like as many people as possible to try them.

This work is not formally assessed as part of this course. However, it does introduce techniques that you will be expected to use during the assessment exercises associated with this course.

B. The Maze Applet

The following applet implements a relatively simple maze. You navigate by pressing the buttons at the top and the aim is to reach the bottom right hand corner.

This applet relies upon two classes:

    This class creates a number of buttons and these are placed on a control panel. It also declares a MazeCanvas (see below). This is then placed below the control panel. An event handler ensures that each time a button is pressed then the MazeCanvas is updated to show that the drone has moved within the maze. If the left button is pressed then the drone moves minus step pixels in the x dimension (step is a constant value set at the start of the class). If the right button is pressed then the mouse moves plus step pixels in the x dimensi on. If the up button is pressed then the ouse moves minus step pixels in the y dimension. If the down button is pressed then the mouse moves plus step pixels in the y dimension.

    This class implements the maze that you see in the main portion of the applet. It centres around the update() method which is called by the event handler in MazeExample whenever the user selects one of the buttons. Update() first checks to see whether the drone can be moved. If the drone would move outside of the boundary of the maze then it stays where it is. If the drone would collide with a wall then it stays where it is. The maze is then repainted to reflect the new position of the drone.
Ok, I know that this is not the world's most exciting game - but your task is to make it much, much more interesting...

C. Your Tasks

The following paragraphs present this week's tasks; try to complete as many as possible because they get more interesting as you continue.

Task 1: Alter the layout of the control panel (basic level of difficulty)

The control keys are not well designed. Several improvements are possible. The first might be to alter the layout so that their position reflects the direction in which they will move you. For example, the Up button should be at the top, the left button should be on the left. You should, therefore, change the FlowLayout of the controls to a BorderLayout and then add the buttons in "North", "South", "East" and "West" positions.

Task 2: Put in an End Point (basic/intermediate level of difficulty)

A further problem with the game is that there is no indication of the end position in the maze. Edit the paint() method in to draw an exit in the bottom left hand corner. You could use the following line:

   canvasG.drawRect(canvas_indent*2, d.height-drone_size*2, drone_size, drone_size);
Remember that the first two parameters specify the upper-left hand corner of the rectangle. This is slightly indented and we have to raise it above the bottom of the canvas (d.height) otherwise we would never see it; it would fall off the bottom of the page. For simplicity, the exit is given the same size as the drone.

Unfortunately, this doesnt tell the user that the rectangle is really the exit point. Futher edit the paint() method to include the word `Exit' using the g.drawString("Hello World!", x, y) method. Hint: look in the API and here for more information on this.

Task 3: Put in a "Reward" (intermediate level of difficulty)

Now that you have indicated the end-point of the maze, you could introduce some reward. One way to do this would be to change the check_dimensions method in as follows:

	private void check_dimensions(int newX, int newY)
		if (at_finish(newX, newY))
		else if (in_bounds(newX, newY) && in_walls(newX, newY))
                        	X = X + newX;
                        	Y = Y + newY;
You will have to write the code that checks whether the drone is at_finish. You will then also have to think of an appropriate reward (you could link this to a web page using the URL techniques shown at the end of Exercise 2.

Task 4: Put in a Score (intermediate level of difficulty)

One of the most important features of a game is that it provides its users with an indication of how well or how badly they are performing. This can be done in the maze, for example, by displaying the number of times that the user has pressed a button while they navigate towards the exit. You could implement this by incrementing a variable inside the action() method of The value of this variable might then be displayed using a label. The quickest way to achive this would be to add the label to the control panel. However, care must be taken to position the score in an area where it will be seen but will not interfere with the users ability to interact with the game. (A better solution would be to create a new Panel to hold the score, in the same way that the controls panel was created to hold all of the buttons).

Task 5: Create Better Mazes (intermediate level of difficulty)

At the moment, the walls in the maze are constructed by a fixed set of lines. These lines are calculated relative to the overall dimensions of the maze canvas. So if the maze is resized then the walls will still be in proportion.

Unfortunately, the code that constructs the walls is not particularly elegant. You could create a class of walls and this would greatly simplify the task of creating more and more complicated mazes. This could implement an array of lines where each line was represented as an array of four integers (X1, Y1, X2, Y2) to denote a line from (X1, Y1) to (X2, Y2). This array might then be passed to the draw_walls() and in_walls() method within

Although it might seem strange to end up with what seems like a software engineering task, this is intended to illustrate how it can be difficult to generate good user interfaces (in this case a challenging game) without a firm foundation in programming skills. By now you should have seen that it's not as easy as it looks...

D. Summary

This exercise first required you to alter the LayoutManagers that were used to assemble the maze applet. You then used some of the graphics facilities of AWT to put in an end point and label it. Greater interaction was added (together hopefully with an element of fun and surprise) by introducing a reward. A label was used to present the player with some feedback on their progress. Finally, a class was created to simplify the task of building more elabourate mazes.

Back to the main index...