CS 124, Spring 2017
Lab 2: Using Subroutines

In this lab, you will write programs that use pre-defined subroutines. In addition to System.out.print, which you encountered in Lab 1, you will use some input routines from the non-standard class TextIO. and some standard functions in the String class. And, as a bonus, this lab introduces Java graphics. You'll learn some basic drawing subroutines, and you will use them to draw a simple picture.

To start the lab, I suggest that you make a directory named lab2 to hold your work for this lab, inside your cs124 directory (but this is not required, you can organize your files as you please). You will need to copy two Java files into that directory: TextIO.java and FirstGraphics.java. You can find copies of these files in /classes/cs124. Assuming that you made a cs124 directory last week, here are commands that you can use on the command line in a Terminal window:

cd cs124
mkdir lab2
cd lab2
cp /classes/cs124/TextIO.java .
cp /classes/cs124/FirstGraphics.java .

Note the space and period at the ends of the last two commands. The period is used in Linux as a name for the current working directory. By the way, if you prefer using a GUI to using the command line, you could also do all of this using file broswer windows. To find the /classes directory, click "File System" in the list on the left edge of a file browser window. Alterntively, you could download the files using the links on this web page.

Your work from this lab must be submitted by the beginning of next week's lab, using the Submit124 web page, http://math.hws.edu/submit124 You will submit five short Java programs, which must be named Random5.java, RootBeerWithInput.java, MyName.java, Conversation.java, FirstGraphics.java. Remember that you do not need to submit all the programs at the same time and that you can resubmit a program as many times as necessary, if you need to make corrections.

Some Style Rules

Starting with this week's lab, your grade will be based partly on program style. When you write a program, it's important to follow rules of good programming style. These rules are mostly for human readers, not for the computer, and therefore the computer won't give you any feedback about them when you compile or run the program. So it's up to you to make sure that your programs show good style. Here are some of the rules that I expect all of your programs to follow:

Exercise 1: A Small Random Program

We start the lab with a short, easy program. The function Math.random() gives you a random real number in the range 0.0 to 1.0 (including 0.0 but not including 1.0). Suppose that you want a random number in the range 0.0 to 5.0. One way that you might think of doing this is to use Math.random() five times and add up the five numbers that you get from that function. This does indeed give a number in the range 0.0 to 5.0, and it does give a "random value", but it's probably not what you really want!

Write a program that uses Math.random() five times to produce five different random numbers. The name of the program must be Random5.java. Add up the five numbers that you get, and output the answer. Run the program a bunch of times and see what's wrong with the result. (Hint: Look for numbers close to 0 or close to 5.)

Add a comment in your program about your observations!

(The point of this exercise is to illustrate that if you want evenly distributed random numbers, you have to be careful how you make them. The right way to get random numbers evenly distributed in the range 0.0 to 5.0 is to compute 5*Math.random().)

Exercise 2: Using TextIO for Input

The file TextIO.java defines some functions that let you read values that are typed in by the user. The basic TextIO input functions are discussed in Section 2.4.3. The ones that you will need in this lab are TextIO.getlnInt(), TextIO.getlnDouble() and TextIO.getln().

The program RootBeer.java that you wrote for Lab 1 is not very useful, since it does the same calculation every time it is run. Make a new version of the program that asks the user to enter the price of a keg of root beer and the number of people who will be at the party. The new program should use the input information when it calculates the number of kegs needed and the total cost of the kegs. The name of the new program must be RootBeerWithInput.java.

While you are improving the program, you should also make it conform to the style rules given above. That is, declare only one variable on a line, and add a comment to the declaration to explain its meaning. Also add a multiline comment at the beginning to explain the purpose of the program. And make sure tht variables that are naturally integers, such as the number of people, are of type int rather than double.

Exercise 3: Using String Manipulation Functions

We have seen that strings are objects and that they come with functions that operate on the string. All the functions that you need can be found in Section 2.3.3.

Write a program that gets the user's name and then does the calculations and outputs specified below. The name of the program must be MyName.java.

The program should ask for the user's full name (first name and last name, separated by a space). It should use TextIO.getln() to read the answer into a variable of type String. You should assume that the user enters a reasonable response. (If they don't, the program can crash, but that's OK—it's the user's fault, not yours.)

Once you have the user's name, use string functions to do the following computations with the string, and display the results (with appropriate labeling):

When the user runs the program, it should work more or less as follows, where the user in this example types in his name as "James Kirk":

Hi!  Please tell me your name.
Type in your first name and last name, separated by a space:  James Kirk

Your full name contains 10 characters
Your name in uppercase letters is JAMES KIRK
Your first name is James
Your last name is Kirk
Your initials are JK

Feel free to modify the format, but you should at least output the required information.

Exercise 4: Converse With Your Computer

You should design and write a program that will hold a conversation with the user. The topic and the structure of the conversation are up to you. Requirements are: You should ask the user at least four questions (and read the user's responses). Some of the responses should be numbers, and you should do at least two calculations using the input numbers. (For example, you could ask what year the user was born and have the computer compute the user's age.) Some of the responses should be strings, such as the user's name or favorite color. You should use the user's inputs somehow in your outputs. (For example, "How about that, Fred, blue is my favorite color too.")

Your grade will be partly based on how natural and interesting the conversation is. Feel free to be amusing, obnoxious, philosophical, or whatever. Don't forget that you have to do two computations with the user's input! A conversation might go something like this:

 Hi, my name is Kirk.  What's your name?
 Spock
 
 Gee, Spock is a funny name.
 Say, how many years old are you?
 187

 Let's see, this is the year 2471, so you must have been born in 2284.
 That was a good year.
   .
   .
   .

But you're not required to duplicate this conversation. The assignment is to make up your own!

Exercise 5: Introduction to Java Graphics

In the last part of the lab, you will get your first taste of GUI programming. At this point in the course, the only thing that you know how to do is to write is a "once-through" list of instructions that is executed from beginning to end — but you can do anything with those instructions, as long as you have access to the right subroutines. In the previous exercises, you used command-line input/output subroutines. In this part of the lab, you will use some of Java's built-in drawing subroutines.

There is a lot about GUI programming that you won't understand for a while, such as how to open windows and respond to the user's actions. But as far as actually drawing on the screen, it all comes down to a bunch of subroutines for drawing basic geometric shapes. The program FirstGraphics.java has a very simple example of this. You can compile and run the program to see what it does. The main() routine of this program creates a window and puts it on the screen; you don't have to understand how that part is done! The actual drawing is done in another routine, which is named paintComponent(). The paintComponent routine contains a list of subroutine call statements. This list of instructions draws the picture. To draw a different picture, you just have to substitute your own list of instructions inside the definition of paintComponent.

Drawing uses (x,y) coordinates, where x goes from zero on the left to some maximum value at the right, and y goes from zero at the top to some maximum value at the bottom. The coordinates for this type of graphics must be integers, not real numbers. (The maximum values for x and y are 800 and 600 in this program. You can probably guess how to change these values if you look at the main() routine.) The following illustration shows the picture that is drawn when FirstGraphics is run. The picture is in the white area. The numbers and arrows show how the coordinates work. Of course, you can compile and run the program to see the picture at full size.

Here is the original paintComponent routine from the program. You should try to understand how it works, after reading the descriptions of the subroutines given below. Make sure that you understand how the coordinates are being used and how these commands produce the picture shown above! You will use a lot of similar commands for your own drawing.

protected void paintComponent(Graphics g) {

   g.setColor(Color.WHITE); // Set color to be used for SUBSEQUENT drawing.
   g.fillRect(0, 0, 800, 600);  // Fill the whole drawing area with white.

   g.setColor(Color.RED);
   g.drawRect(10, 10, 300, 150); // Draw the outline of a rectangle.

   g.setColor( new Color(0,150,0) ); // (A darker green than Color.GREEN.)
   g.fillOval(355, 15, 290, 140); // Draw a filled-in oval.

   g.setColor(Color.CYAN);
   g.drawLine(20, 200, 780, 580); // Draw two lines to make a big "X".
   g.drawLine(20, 580, 780, 200);

   g.setColor(Color.BLACK);
   g.drawString("Hello World!", 350, 300);  // Draw a string in default font.
   g.setFont(new Font("Serif", Font.PLAIN, 36));
   g.drawString("Goodbye!", 350, 500);  // Draw a string using a bigger font.

}

For the final assignment of the lab, you should modify FirstGraphics.java to draw a different picture. Erase everything inside the printComponent routine, and replace it with your own code. (To start, you might want to comment out the code instead of erasing it, by enclosing it between /* and */, but you should remove the old code before you turn in the program. Try to make a picture of some recognizable object, such as a house, a boat, a face, or a snowman. Maybe use a multicolor background made of two rectangles (representing ground and sky). Add some detail, like clouds or stars. At a minimum, your picture should use at least a dozen drawing commands and several different colors, and you should draw at least one String (maybe containing a title for your picture). Grade will be based partly on ambition and execution—and maybe a little bit on artistic merit, though I'm not really the one to judge that. (But I don't expect you to spend a huge amount of time on this. Some people in past classes may have gone a little overboard.)

The following subroutines are available for you to use in the paintComponent routine:

Predefined colors for use as the "c" value in g.setColor(c) are as follows: Color.BLACK, Color.WHITE, Color.GRAY, Color.LIGHT_GRAY, Color.DARK_GRAY, Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.CYAN, Color.MAGNETA, Color.ORANGE, and Color.PINK. You can also create Color objects to represent other colors. Some examples:

g.setColor( new Color(150,70,0) );    // brown
g.setColor( new Color(170,225,255) ); // sky blue
g.setColor( new Color(0,130,0) );     // dark green

The three numbers in parentheses must be integers in the range 0 to 255. They give the red, green, and blue components of the color. (Try the "color picker" at http://www.w3schools.com/colors/colors_picker.asp. You want to use the "rgb" values for the color.)

There are no predefined fonts, but you can create Font objects to represent a variety of font sizes and styles. For example:

g.setFont( new Font("Serif", Font.PLAIN, 18) );   // A smallish regular font.
g.setFont( new Font("SanSerif", Font.Bold, 72) ); // A big boldface font.
g.setFont( new Font("Serif", Font.Italic, 36) );  // A mid-sized italic font.

The first parameter to new Font() is a font name and the second specifies the style; use the constants shown in this example. The third parameter gives the size of the font in "points", where 100 points is usually about one inch on a desktop computer screen.