CS 124, Spring 2014
Lab 2: Functions, More I/O, and Some Graphics
In this lab, you will write programs that use some of the built-in Java
functions that are available in the Math
class and in objects
of type String
. You'll also get more practice with
text input and output. 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, you should make a directory named lab2 to hold your work for this lab. The exercises in this lab will require two non-standard Java files: TextIO.java and FirstGraphics.java. You need to put these files into your lab2 directory. You can find copies in /classes/cs124. Once again, here are the commands for doing all this 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. (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.)
Your work from this lab is due at the beginning of next week's lab. As usual, when you have finished this lab, you should copy your entire lab2 folder into your homework directory in /classes/cs124/homework. Make sure that your solutions to all five exercises are in the lab2 folder that you submit!
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:
- Use indentation to show the structure of the program. For example, indent the main routine inside the class, and indent the statements inside the main routine. Each level of indentation should be 3 or 4 spaces.
- Use spaces and blank lines to make the program easier on the eyes. For example, it's a good idea to always put spaces around the "=" in an assignment statement. And it's a good idea to put blank lines before and after the main routine, and possibly between sections of the main routine that perform different tasks.
- You should declare just one variable per line (or, in some cases two or three closely related variables).
- Almost every variable declaration should have a comment to explain the purpose of the variable in the program. These are generally one-line comments, starting with //, on the same line as the variable declaration. These comments should describe the purpose of the variable and/or how it is used in the program.
- Every variable name should begin with a lower case letter. If the name consists of
several words, each word after the first should be capitalized. For example:
myInterestRate
. - Every class name, such as the name of the program, should begin with an upper case letter.
If the name consists of several words, each word should be capitalized. For example:
InterestCalculator
. - Names of variables and classes should be meaningful whenever possible.
InterestCalculator
andmyInterestRate
are meaningful names.MyClass
,IC
, andx
are not. - Use appropriate types. For example, a variable that is naturally an integer should have
type
int
, not typedouble
. - There should be a multi-line comment for the program as a whole that explains the purpose of
the class and, when appropriate, how to use it. This comment goes at the beginning of the java
file, just before
public class...
. - Do not write excessively long lines. Ideally, lines should be limited to 80 characters (although it's hard not to creep above that at times).
- When doing input/output, you should generally prompt the user for inputs, and you should label the outputs. The user must be able to understand what is going on. Include appropriate spaces in your prompts and labels. For example, an output such as "The answer is27" should really be "The answer is 27", with a space before the 27.
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. 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 Some Math Functions
Recall that the standard Math class comes with a variety of
functions such as Math.sqrt(x)
, Math.floor(x)
,
Math.sin(x)
, and Math.abs(x)
.
As another warm-up exercise, write a program that reads a real number from the user and applies several functions from the Math class to it. You should find the values of at least six different Math functions, using the user's number as the parameter to each function. Output the values. Don't forget to label each output clearly!
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.2.
Write a program that asks the user to enter his or her full name
(fist name and last name, separated by a space). Use TextIO.getln()
to read the answer into a String variable. 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 various string functions to do some computations with the string and display the results. In particular,
- Tell the user how many characters there are in the name.
- Print a copy of the name with all the letters in upper case.
- Extract the user's first name and last name into two new variables. (Look for the space that separates the names! We did an example like this in class.) Output the user's first name and last name on separate lines.
- Output the user's initials (the first letter of the first name and the first letter of the last name).
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 is up to you. Requirements are: You should ask the user at least five 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 some computation 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. Right now, all you can 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 0 on the left to some maximum value at the right, and y goes from 0 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 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 that 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. 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
(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:
g.drawLine(x1,y1,x2,y2)
-- Draws a straight line from the point (x1,y1) to the point (x2,y2).g.drawRect(x,y,w,h)
-- Draws the outline of a rectangle whose upper left corner is at the point(x,y)
. The width and height of the rectangle are specified byw
andh
.g.fillRect(x,y,w,h)
-- Draws the same rectangle asg.drawRect(x,y,w,h)
, but filled in with color instead of just outlined.g.drawOval(x,y,w,h)
-- Draws the outline of the oval that just fits inside the rectangle that would be drawn byg.drawRect(x,y,w,h)
. For a circle, w and h should be the same number.g.fillOval(x,y,w,h)
-- Draws a filled-in oval.g.drawString(str,x,y)
-- The first parameter,str
, must be a string; this string is drawn into the picture. The left endpoint of the baseline of the string is at the point(x,y)
. (The baseline is the line on which the string is drawn; the bottoms of letters such as "y" and "g" extend below the baseline.)g.setColor(c)
-- Changes the color that will be used for drawing. The new color applies to drawing commands that follow thesetColor
commands, up until the nextsetColor
command.g.setFont(f)
-- Specifies that the computer should use the fontf
for subsequent calls tog.drawString
. The font determines the size and style of the characters that are drawn bydrawString
.
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. The give the red, green, and blue components of 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".