CPSC 124 (Fall 1998): Lab 8
More Arrays and Components
WELCOME TO THE EIGHTH LAB for Computer Science 124. In this lab, you will work on a simple drawing program that lets the user draw multicolor lines. In order for the applet to redraw itself properly, the lines must be stored in an array. This applet also introduces the MouseListener interface, which is used for handling mouse clicks. In the second exercise of the lab, you'll get more experience working with various types of components.
Before you begin, copy the folder /home/cs124/lab8 into your home directory.
The exercises at the end of the lab are due in class on the Monday following the lab.
Outline of the Lab
Drawing with Lines
A component such as an applet or canvas should be able to completely redraw itself when necessary, for example when it is covered up and then uncovered. This means that it is not good form to simply draw something on the component. You also should have some way to remember what is displayed, so that it can be redrawn by the paint() method of the component. In this exercise, you will use an array to store information about lines that have been drawn by the user in a simple drawing applet.
An unfinished version of the applet is in your lab8 directory. You can run it with the command "appletviewer draw1.html". The applet consists of a canvas with several Buttons and a Choice menu below it. You can draw a line on the canvas by clicking your mouse button, holding down the button, and releasing the mouse. The line is drawn between the point where you press the mouse button and the point where you release it. The color of the line is given by the setting of the Choice menu. Except for the "Undo" button, the applet is functional. However, the lines will disappear if you cover and uncover the applet window.
Your assignment is to modify the SimpleDrawApplet.java file so that the applet can properly redraw itself. You will also implement the "Undo" function. Since the actual drawing is done on the canvas, all the work that you do will be in the SimpleDrawCanvas class.
The data about the lines that have been drawn will be stored in an array. You'll find that the following class is already defined in the file:
class Line { int x1, y1; // one endpoint of the line int x2, y2; // second endpoint of the line Color color; // color of the line }You should use an array of Line objects. You can allow space for, say, 500 lines, which is more than will ever be used in practice. Since the number of lines varies as the applet runs, you are actually working with a partially full array. This means that you also need an int variable, such as lineCount, to keep track of how many lines are actually stored in the array.
Every time the user draws a line, you should add the line to the array (in addition to displaying it on the canvas, as is already done in the original version of the applet). You should add a public void paint(Graphics g) method to the canvas class that will draw all the lines in the array. The "Undo" operation should remove the most recently drawn line from the array. Fortunately, this is quite easy: Just change the value of the lineCount variable and call repaint(). (Of course, if the user tries to "Undo" when there are no lines at all in the picture, you shouldn't do anything.) You will also have to modify the doClear() routine to make it clear the data structure before calling repaint().
You can try a completed version of the applet on a separate page.
A GUI for Riemann Sums
For your second programming assignment, you wrote a program that could approximate the area under a curve using various type of "Riemann Sums" (the left endpoint rule, the right endpoint rule, the midpoint rule, and the trapezoid rule). In the second exercise of the lab, you will work with an applet version of the program. The applet has a GUI that lets the user enter data and click on a button to get results. Your lab8 directory contains an unfinished version of the applet, which you can run with the command appletviewer sums.html. In this version, all the components are in place, but clicking on a button only produces a message telling the user that the button was clicked.
Your assignment is to modify the RiemannSumsApplet.java file so that when a button is clicked, the applet will compute the corresponding Riemann sum and display the result in a message. However, if the user has entered illegal data, you should display an appropriate error message instead. All the work can be done in the actionPerformed method, which will become fairly long. Note, however, that the applet already includes subroutines for computing the various types of Riemann sum, so you won't have to write those.
The applet uses two new types of Component. A component of type Label is used to display a message to the user. A Label has a setText() method that can be used to change the text of the label. Examples of this can be found in the actionPerformmed method of the original RiemannSumsApplet.java.
The applet uses four components of type TextField, where the user can type in values for the function, the left endpoint, the right endpoint, and the number of subintervals. With a TextField, you don't have to worry about the component until you actually need the data that it contains. A TextField component has a method, getText(), that can be used to retrieve the String that the component contains. For example, if leftEndpointBox is a TextField, then
String leString = leftEndpointBox.getText();will get the contents of leftEndpointBox and store it in the variable leString. Of course, for this applet, not every string will represent legal data. You should use a try...catch statement to check whether each item of data is legal. The value in functionBox must be a legal function definition that can be used to construct an object of type Expr. You already know how to do that. The values in intervalCountBox must be an integer. A string, icString can be converted to an integer with a code segment of the form:
try { N = Integer.parseInt(icString); } catch (NumberFormatException e) { ... // handle the error }The data in the other two boxes should be real numbers. Unfortunately, it is even more difficult to convert a string into a double value. You can do this with a code segment of the form:
try { A = Double.valueOf(leString).doubleValue(); } catch (NumberFormatException e) { ... // handle the error }If you find an error in one of the data boxes, you should display an error message and return immediately from the actionPerformed() method. As a courtesy, its a good idea to hilite the text in the TextField where the error was found and give the input focus to that TextField. This lets the user simply start typing to correct the error. You can do this for functionBox, for example, with the two commands "functionBox.selectAll();" and "functionBox.requestFocus()".
You can try a completed version of the applet on a separate page. Make sure that you run this applet to see what your own applet should do!
Exercises
Exercise 1. (10 points) Complete the SimpleDrawApplet, so that it uses an array of Lines, as described above. Turn in a print out of your completed SimpleDrawApplet.java file. It is not necessary to post your applet on the Web. I will access it in your account if I have any questions.
Exercise 2. (10 points) Complete the RiemannSumsApplet, as described above. Turn in a print out of your completed RiemannSumsApplet.java file. Again, it is not necessary to post your applet on the Web.
Exercise 3. (5 points) Write a short essay to explain why an array was necessary in Exercise 1. Why would it be difficult to make this applet work correctly without using an array or some similar data structure?
Exercise 4. (5 points) Write a short essay comparing the original Riemann Sums program, which you wrote for Programming Assignment 2, with the applet version, which you worked with in this lab. Which is better for the user? Why? What about the programmer? What happened to the loop that was in the original program? Why doesn't the applet have a while loop?