Document

advertisement
Introduction to
Computer Science
CSC 2011
Laboratory Manual
Mark A. Boshart
© 2006 Mark Boshart
Contents
CSC 2011 Syllabi
Lab 01:
Getting Started
Lab 02:
Console I/O and Calculations
Lab 03:
Static Methods and Primitive Data Conversion
Lab 04:
Using Objects
Lab 05:
Conditionals
Lab 06:
Loops
Lab 07:
Writing Classes
Lab 08:
Overloading Methods
Lab 09:
Interfaces and Interface Type
Lab 10:
Object Arrays, ArrayList, 2D Primitive Arrays
Lab 11:
Inheritance Hierarchies
Lab 12:
Collection Polymorphism
Lab 13:
Exception Handling and File I/O
Lab 14:
Graphics and GUIs
CSC 2011 Lab: Introduction to Computer Science
My office hours: MW 10:00 – 12:00 c.
Prerequisite: CSC 2001
Corequisite: CSC 2010
Download the doc for the 2010/2011 syllabi, lab assignments.
Section 1:
Lab TA: Michael Baldwin (Bruner 405)
Email: mkbaldwin21@tntech.edu
Office Hours:
M W: 12:30-2:30
T: 1:30-3:30
R: 9:00-11:00
Section 2:
Lab TA: Emily Sherrill (Bruner 405)
Email: emsherill21@tntech.edu
Office Hours:
M: 11:00-12:00 1:00 - 3:00
T: 8:00-12:00 1:00 - 3:00
W: 11:00-12:00 2:00 - 3:00
R: 8:00-9:00 11:00-12:00 1:00 - 3:00
F: 8:00-10:00 11:00 - 12:00
You will demonstrate your in-class labs (as a team) to TA assigned to your
class and you will demonstrate your post-labs (individually) to TA assigned to
your class.
Sheikh K. Ghafoor
Email: sghafoor@tntech.edu
Lab Guidelines
You are expected to have read the entire lab before coming to the lab and to have
reviewed the material described in the pre-lab. You will also want to read the detailed
instructions within the starting code for each lab as important points are made there as
well.
Lab time will be allocated as follows:
Five minutes for lab setup. This will involve taking roll, downloading starting source
code, and assignment of a partner for the lab. You will be assigned a different
partner for each lab.
Ten minutes for a discussion of background material and possible ways to tackle the
solution. I expect everyone to participate by asking questions and by suggesting ways to
tackle the solution that I did not cover.
Ninety-five minutes to implement and to test your solution.
When you are ready, I will verify that your solutions are correct.
Total time: 110 minutes for each lab.
Grading Policy
Missed labs can only be made up (on your own time and by yourself) with proper
documentation of exceptional circumstances (i.e. a doctor's note or other authorized
absence).
In order to pass, you must attend 13 out of 14 the labs and make a decent attempt at
the in-class lab exercises. You must also participate in class discussions on a regular
basis.
In order to make a "C", you must satisfy all the requirements for passing and
successfully complete 12 out of 14 of the in-class lab exercises. You must complete
labs 11, 12, and 13. You may only turn in an in-class lab if you are present for
the entire lab during the scheduled lab time, unless your team successfully
demonstrated the in-class lab exercises before the end of the lab, or you have
documentation of exceptional circumstances. Roll will be taken at the beginning and the
ending of lab. If you are late to the point that partners have already been rearranged
due to your tardiness, you will not be allowed to participate in the lab and will be
marked as absent for the lab. If you cannot complete the in-class lab exercises during
the scheduled class time, you may continue to work on the exercises outside of class
(see below).
Your team has until:
Monday at 2:30 PM to complete the in-class lab and the individual post-labs (if you
choose to do the post-labs).
In order to make a "B", you must satisfy all the requirements for a "C", and you must
successfully complete 9 of the post-lab exercises individually.
Post-labs are due according to the same schedule (above) used for in-class labs and
must be based on a lab with an in-class portion that you have completed.
In order to make an "A", you must satisfy all the requirements for a "B", and you must
successfully complete 13 of the post-lab exercises individually.
Handing In Your Lab
I am always willing to help with any lab or post-lab questions that you may have. To
officially turn in your work, please follow the guidelines below. The Lab TAs (and/or
myself) will be keeping track of which in-class labs and post-labs that you have
completed.
The in-class portion of the lab should be shown (or emailed) to the Lab TA in charge of
your lab section. Simply demonstrate that your lab is working. If the lab has multiple
parts, you will need to demonstrate each part as you complete them. You will also be
asked about your observations concerning specific lab sections as noted in the lab
instructions. After all parts have been demonstrated, your team will be checked off as
having completed the in-class portion of the lab.
Depending on the specific post-lab, there may be some additional programming, a short
paper, or both to hand in. If a post-lab has a programming component, you will need to
demonstrate it (or email it) to the TA (there is no need to print out your source code).
Post-labs are done individually, so everyone handing in a post-lab will need to
demonstrate their work. If the post-lab has a paper component, you will need to print
this out and give it to me as well.
I recommend that you demonstrate your in-class labs and post-labs. This way, specific
problems that are encountered can be discussed in person. If you choose to email your
in-class labs and post-labs, you will only be given a brief description of any problems (if
there are any) with your work. If you email your work, zip all of your files up and
use your name, the lab number, and in-class or post-lab to create the title for
the zip file.
Labs
1) Getting Started




Compiling
Running
Identifiers
Comments
o Multi-line
o End of line
2) Console I/O and Calculations


Console I/O
o Keyboard class
o Repeating input
o Reporting output
o String concatenation
Calculations

o
o
o
Syntax
Runtime
Logical
3) Static Methods and Primitive Data Conversion



Static Methods
o Parameters
o Return Types
o Nesting Method Calls
Primitive Data Conversion
o Widening
 Assignment
 Arithmetic
o Narrowing
 Casting
Code Reuse
5) Conditionals


If - Else If - Else
o Checking User Input
o Nested Conditionals
o Complex Boolean Expressions
Switch
7) Writing Classes







State variables
o integers
o booleans
o Strings
Visibility modifiers
o private state variables
o public get/set methods
o private helper methods
toString to report state
Controlling state changes with set methods
Driver class
Object parameters
UML
9) Interfaces and Interface Type




Interfaces
Separate Implementations of a Common Interface
o Parametric Line
o Slope - Intercept Line
Hiding Implementation (Abstraction)
o Interface Type
o Factories
Still More UML
11) Inheritance Hierarchies

o
o
o
Errors
Inheritance
o extends
o super
Primitive data types
Arithmetic operators
Math class
4) Using Objects



String Class
o Pig Latin Translator
Random Class
o Abstraction
o Code Reuse
DecimalFormat Class
o Using Formatting Patterns
o Currency Pattern
6) Loops


While Loop
o "Hiding" Nested Loops
o Do-While Loop
For Loop
8) Overloading Methods







Reinforce
o Constructors
o Get/Set
o Encapsulation
Aggregation (HAS-A)
equals
this
Method Overloading
Static Methods and Variables
More UML
10) Object Arrays, ArrayList, 2D Primitive Arrays






Reinforce
o Constructors
o Loops
Randomizing Object Arrays
For-each statement
Object Arrays as Parameters/Return Values
ArrayList
Primitive Arrays
o 1D
o 2D
12) Collection Polymorphism

Polymorphism
o Inheritance Polymorphism
o Interface Polymorphism
protected
abstract classes and/or methods
overriding and overloading
 equals
 constructors
o implements
o indirect
Reinforce
o Comparable Interface
o Get Methods
o
o
o

13) Exception Handling and File I/O


Exceptions
o Custom Checked Exceptions
 Throwing Exceptions
 Error Messages
 Additional Information
o Handling Exceptions
File I/O
o Text Files
o Serializing Objects


Reinforce
o Comparable Interface
o ArrayList
o for-each
o Set Methods
Testing
14) Graphics and GUIs



Reinforce
o Has-a Relationship
o Is-a Relationship
o Object Arrays
o Interfaces
Basic Graphics
o Shape Hierarchy
o Visual Interface
o Graphics class
Basic GUIs
o Mouse Events
o Timer
o repaint
I reserve the right to modify the contents of the labs.
Honesty
Students are encouraged to obtain limited help and/or ideas from one another.
However, copying assignments or allowing assignments to be copied will not be
tolerated. The penalty for cheating in the class is an "F" for a final course grade.
Attendance Policy
You are expected to attend every lab. You are responsible for all assignments and
material covered and all issues discussed during all lab meetings whether you are
present or not. Makeup labs will not be accepted without proper documentation for an
excused absence.
Disabilities
Students with a disability requiring accommodations should contact the Office of
Disability Services (ODS). An Accommodation Request (AR) should be completed as
soon as possible, preferably by the end of the first week of the course. The ODS is
located in the Roaden University Center, Room 112; phone 372-6119.
Contact
Email: sghafoor@tntech.edu
Laboratory 1: Getting Started
Java API
Pre-lab:
Be comfortable with Windows Explorer. A keyboard short cut to launching Windows
Explorer is to press the Windows key and E at the same time.
Compilers and Interpreters
General Procedure:
Initially, you use an editor as you type a program into a computer and store it in a file.
After editing and saving your program, you attempt to translate it from "high-level",
English-like code into a form that can be executed by the computer which requires 1’s
and 0’s. The steps are outlined on my web site here. That translation may result in
errors, in which case you return to the editor to make changes to the code to fix the
problems. Such errors are called syntax errors. Once the translation occurs
successfully, you can execute the program and evaluate the results. If the results are
not what you want (logical errors) or your program can't complete (run-time errors),
you again return to the editor to make changes.
A compiled language has a compile step. (C/C++)
The translation of source code into machine language for a particular type of computer
architecture can occur in a variety of ways. A compiler is a program that translates code
in one language to equivalent code in another language. The original code is called
source code, and the language into which it is translated is called the target language.
For many traditional compilers, the source code is translated directly into a particular
machine language. The translation process occurs once for a given version of the
program. The program can then be directly executed whenever needed. However, this
will only work for one particular system architecture without recompiling (i.e. PC vs.
Mac). Each type of computer has its own set of requirements. Thus, the same program
will have to be compiled multiple times in order to be run on different computer
architectures.
An interpreted language does not have a compile step.
An interpreter is similar to a compiler but has some important differences. An interpreter
interweaves that translation and execution activities. A small part of the source code,
such as one statement, is translated and executed. Then the next statement is
translated and executed, and so forth. The program generally runs slower as the
translation process occurs during each execution.
Java combines the compilation and translation processes.
The Java compiler translates Java source code into Java bytecode, which is a
representation of the program in a low-level form similar to machine language code.
This translation is performed during the javac step (see later) that checks for syntax
errors. The Java interpreter then reads Java bytecode and executes it on a specific
machine (the java step).
Java bytecode has the advantage that it is not tied to a particular processor type like
traditional compilers which compile to the machine code for a particular computer
architecture. Java is, architecture neutral, and is easily portable from one machine to
another. The only restriction is that there must a Java interpreter installed on the
computer on which the Java bytecode is to be executed. Each type of computer
architecture has its own version of the Java interpreter which converts the bytecode the
rest of the way to machine code for the computer on which the program is being run. As
the interpreters are installed ahead of time, a particular Java program can be run on
different computer architectures without repeating the translation step.
Thus, Java is faster than traditional interpreters as the Java interpreter only needs to
translate from bytecode to machine code. However, Java is still slower than traditional
compilers as some interweaving of translation and execution is still performed. Also,
there is no need to recompile to bytecode when running a Java program on multiple
computer architectures. Simply install the Java interpreter on each machine on which
you wish to run your Java bytecode.
Lab:





Compiling
Running
Identifiers
Comments
o Multi-line
o End of line
Errors
o Syntax
o Runtime
o Logical
Part I: Compiling and Running a Program
First, you will need to open a text editor. You can use any text editor that you want, but
these lab instructions assume Notepad. Launch Windows Explorer. Navigate to the
folder where you want to store your work. Right click the folder and select Launch
Command Prompt. Type notepad in the command prompt window.
Type in the following text exactly as it appears below into notepad. Note that the name
of our class is FirstProgram. You can identify the name of the class because it occurs
after the keyword class. You will need to use this class name when saving your
file later.
Now you need to save the file. Go to the File menu and select Save As. Navigate to the
folder where you are working. This should be the same folder where your opened a
command prompt earlier. Set the file name to FirstProgram.java. As noted earlier, all
Java files require that the file name match the class name. Also, make sure that the
file type is set to All Files. Otherwise, your file name will have a .txt extension added
automatically. In order to compile a program, the Java compiler requires a .java
extension, not a .txt extension. Click Save.
Compile the file by typing javac FirstProgram.java in the command window.
You should have gotten a message in the command window that states that the symbol
string was not found. This is because Java is case sensitive, and you need to use the
symbol String. This type of error is called a syntax error. The Java compiler could not
figure out what was meant by "string". There can be no ambiguity in our code or the
compiler will complain.
Fix this error by replacing string with String, and repeat steps 3 and 4 (if you received
other errors, fix those as well). Note that when saving your file now, you can select Save
rather than Save As, as the file to write to has already been specified, and your old work
will be overwritten with your changes.
Type dir in the command prompt. Note that there is a file called FirstProgram.class.
This is the Java bytecode file, and was created when our program compiled with no
syntax errors. The Java interpreter needs this file to execute your program.
Type java FirstProgram in the command prompt. Note that no extension is needed.
The interpreter knows that it is going to use the .class file. Hopefully, your program
executed and printed two lines of text to the screen.
Part II: Identifiers
There are three types of identifiers in a program.



Reserved words of the Java language
Names chosen by another programmer
Names chosen by us
In FirstProgram, class is an example of a reserved word. It has a specific meaning to
Java. There are specific locations where Java expects reserved words to be used. They
should not be used anywhere else. Change class to cls, and repeat the steps for
compiling and running. What happened? Change this back.
Other keywords include public, static, and void. You will know what these reserved
words are for later in the course.
An example of the second type of identifier is String. This name was chosen by another
programmer. You are telling Java that you want to make use of someone else's code, a
very important idea in computer science. You can save a tremendous amount of time
coding and testing if you make use of existing code. In order for you to make use of the
code that someone else wrote, you must use the name they selected (remember, Java is
case sensitive) to refer to their work. You have already experimented with changing this
type of an identifier in Part I. If the incorrect identifier is used, the Java compiler cannot
find the code that you want, and will issue an error message.
In our program, args is an example of an identifier chosen by us. Thus, you are free to
change it, as long as you change it everywhere it occurs (there is only one occurrence
for args in our example). However, you must follow the rules for identifiers. An identifier
may contain letters, digits, the underscore character, and the $ character. The only
other restriction is that an identifier cannot start with a digit. Try changing args to
1args and compiling. What happened? Next change args to _1args and repeat the steps
for compiling and running. What happened? Change back to args.
Finally, change the text inside the double quotes to something else and repeat the steps
to compile and run. What happened? The text in the double quotes are not specific
instructions for running the program (this is called a String literal). This is the text that
is going to be written to the screen when the program runs, exactly as it appears in your
file. It is not an identifier, so it can be changed to anything.
Part III: Comments
There are two ways to insert comments into a program.


/*...*/ (multi-line)
// (end of line)
Multi-line comment example:
/*
Here is an example
of a multi-line comment.
*/
Everything between the /* and the */ is ignored by the compiler.
End of line comment example:
System.out.println("Some text"); //Here is an example of an end-of-line comment.
Everything after the // to the end of that line is ignored by the compiler.
Using the multi-line comment, document the top of the program (class) to describe the
purpose of the program (class). Make sure that your comment spans multiple lines.
Repeat the steps to compile and run. The text in the comment should have been ignored
by the compiler.
Using the multi-line comment, document your main method. Describe the purpose of the
main method and what the method does in general.
Using the end of line comment, put some text after the first System.out.println
indicating that the two lines of text are going to be printed to the screen.
Repeat the steps to compile and run. Again, your comments should be ignored.
Part IV: Errors
As noted earlier, there are three types of errors.



Syntax (already discussed)
Runtime
Logical
Insert the following line of code at the end of your main method:
System.out.println(3/0);
In this line, you are dividing 3 by 0 and printing the result to the screen. Compile and
run this modified program. There are no syntax errors, so the program compiles. That
is, it is clear to the compiler that you want to divide one number by another. There is no
ambiguity in this instruction. However, there is still a problem with this line of code.
Division by 0 is not defined. This problem is not checked for by the compiler, and will
only be detected when the interpreter runs the line with the problem. An error that is
encountered during the running of the program is a runtime error. Take this line out
before proceeding.
Insert the following lines of code at the end of your main method exactly as it appears
below (you are not expected to understand all of the symbols below):
System.out.println("3 times 2 = " + (3 * 3));
Compile and run your program.
Although fixing this particular "error" is simple, in a program with many complex
calculations, it can be very difficult to find and correct such errors. This is because there
are no error messages, but the answer that the program gives is simply incorrect. Such
errors are called logical errors. Fix this error (hopefully, how to fix this is self-evident).
Post-lab:
About You
Write a program to print your name, your birthday, your hobbies, your favorite books,
and your favorite tv show. Call it ComplexText.java. Use only one System.out.println
statement. Use quotes in your output where appropriate, and place each item
about you on a separate line. That is, write your single System.out.println statement
over several lines, rather than one very long line. Make sure that word wrap in notepad
is turned off. Do not declare any String variables.
You will need to read about escape characters on page 67 and about String
concatenation on page 64 of your textbook.
Laboratory 2: Console I/O and Calculations
Java API
Keyboard Documentation
Pre-lab:
Make sure that you are comfortable with the primitive data types and the primary
arithmetic operators. Review compiling and running a Java program from Lab 1. Keep
your work for this lab as you will be using it in the next lab.
Download the Keyboard class and place it in the directory where you will be working for
this lab. Take a look at the documentation for the Keyboard class. You will use the
Keyboard class to obtain input from the user. Remember that to call a static method
(the only kind that we have seen so far), you use the name of the class followed by a
dot and the name of the method.
You will also need to make use of the Math class in this lab. The methods are selfexplanatory. The Math class is automatically available to you, so you don't need to
download anything. Call methods using the class name just like for the Keyboard class.
Lab:


Console I/O
o Keyboard class
o Repeating input
o Reporting output
o String concatenation
Calculations
o Primitive data types
o Arithmetic operators
o Math class
Part I: Obtaining and Confirming User Input
Start a new class called Points. Remember to work in the same directory where you
saved the Keyboard class. Obtain 4 pieces of information that will define two points from
the user as indicated below:
(x0, y0) and (x1, y1)
Indicate with an informative prompt exactly what you expect to obtain from the user.
Make sure to allow numbers with fractional parts to be inputted.
After the input has been obtained, print back to the screen exactly what you obtained
from the user. Display the inputted values in (x, y) format. Indicate the first point and
the second point. You will need to use string concatenation. Refer to the figure later in
the lab.
Part II: Performing Calculations
Next compute the distance between the two points using the distance formula:
√(x1 - x0)2 + (y1 - y0)2 (everything is under the radical)
Use the information that you have retrieved from the user to compute the distance
between the two points. Do not use the Math class to compute the squares, but
you may use the Math class to compute the square root.
Print out the results to the screen using a complete sentence. Refer to the figure.
Part III: Slope and Intercept
Enhance your program to compute the slope and y-intercept of the line joining the two
points. Compute the slope first using both points obtained from the user. Next, compute
b. To do this, you will use the slope just computed and one of the two points (you
choose) obtained from the user. Use the following formulas (m is the slope and b is the
y-intercept):
m = (y1 - y0) / (x1 - x0)
y = m*x + b
Print out the equation of the line (y = m*x + b) with your computed slope and yintercept. Use a complete sentence.
Part IV: Documentation
Document your class, main method, and important individual lines using both multi-line
comments and end of line comments as you did in Lab 1.
Part V: Approximation Errors
The trigonometric functions sine and cosine can be approximated as follows:
sine(x) = x - x3/3 + x5/120 - ...
cosine(x) = 1 - x2/2 + x4/24 - ...
where x is in radians and radians = degrees * pi / 180
The tangent is defined as sine/cosine.
Write a program (Trig.java) to request an angle from the user in degrees. Convert
degrees to radians. (use Math.PI for pi, a constant defined in the Math class). Use a
Math class method to obtain xy (search for the method to use in the Java API). Report
the sine, cosine, and tangent using the approximations above. You only need to use
the terms explicitly shown above in your computation. State that they are
approximate values.
Find and use an appropriate method in the Math class to obtain an "exact" value (really
just a much better approximate value) for the sine, cosine, and tangent given an angle
in radians. Compute the percentage error in your approximate calculation for the sine,
cosine, and tangent.
% error = 100 * (approximate value - exact value) / (exact value)
Report the percentage error obtained for sine, cosine, and tangent.
Post-lab:
Floating Point Accuracy
As discussed in class, a float uses 32 bits to store a value (a bit is a one or a zero).
Thus, there is a limit to how accurate your computations can be in a program. The first
bit stores the sign (0 for a positive number, 1 for a negative number). The next 8 bits
store the exponent. The last 23 bits store the mantissa. For example, 7.5f is
represented in binary as:
01000000111100000000000000000000
OR
0 10000001 11100000000000000000000 (broken into the three regions, sign,
exponent, and mantissa)
The first bit, a zero, indicates that the sign is positive.
The next 8 bits give the exponent, but in a form called excess 127. This means that the
exponent that we compute from the 8 bits for the exponent is 127 larger than the actual
exponent. Since computers operate on bits, everything is in binary, so we need to
convert the exponent from binary to decimal. The exponent in base 10 is computed as
1x27 + 0x26 + 0x25 + 0x24 + 0x23 + 0x22 + 0x21 + 1x20 = 129. Thus, the exponent is
129 in base 10 (or decimal), so the actual exponent is 2 (129 - 127 = 2).
Note that 2 is raised to the given exponent and this result is multiplied by the
mantissa (see next).
The last 23 bits represent the mantissa, or the fractional part of the number. It is
evaluated as follows:
1 x 2-1 + 1 x 2-2 + 1 x 2-3 + 0 x 2-4 + ... the remaining bits are all zeroes.
This is 0.5 + 0.25 + 0.125 = 0.875. Finally, add 1 to the mantissa.
So we have:
+ 1.875 x 22 = 7.5f, which is a floating point number that can be represented exactly
in Java.
Assume that 12.36f is represented as 01000001010001011100001010001111. This
bit pattern is not exactly 12.36, but it is very close. As a float can only hold 32 bits,
many numbers cannot be represented exactly, and this can introduce errors in
calculations. Using the rules described above, write a program to compute the decimal
number that the bit pattern for 12.36f actually corresponds to. It will not be exactly
12.36, but very close. Your program does not have to be interactive. It only needs to
be able to compute the decimal number for the above bit pattern. Since you are
computing the error contained in floats, should you use floats or doubles to perform
your calculation? Print out your result.
Next, compute the percentage error of the value just computed from the actual value.
As your computed value represents the "approximate" value, should you use doubles or
floats to represent the actual value, which you need in order to compute the percentage
error? Print the percentage error.
Over the course of the semester, you may encounter strange output that is related to
the fact that many numbers cannot be represented exactly. To see what this strange
output might look like, add a few more statements to your program. Declare a float and
give it the value 12.36f. Print the result. Now add 100.2f and then immediately subtract
100.2f. Print the result. Write a paragraph describing your strange output and speculate
as to why you get what you get.
Laboratory 3: Static Methods and Primitive Data Conversion
Java API
Keyboard Documentation
Pre-lab:
Make sure that you are comfortable with static methods and primitive data conversion.
Remember, there are several types of primitive data conversion:
1.
2.
3.
4.
5.
(A) assignment
(B) arithmetic
(C) casting
(D) parameter
(E) return
Download the Keyboard class and place it in the directory where you will be working for
this lab.
Lab:



Static Methods
o Parameters
o Return Types
o Nesting Method Calls
Primitive Data Conversion
o Widening
 Assignment
 Arithmetic
o Narrowing
 Casting
Code Reuse
Part I: Static Methods
Modify your Lab 2 work to include and use the following methods:
1. public static double getInput(String prompt)
//obtains input from the user given the specified prompt (use
Keyboard.readDouble)
//you can only return one value from a method at a time
//you will call this method 4 times
2. public static String printPoint(double x, double y) //returns a String representing
one xy-pair "(x, y)"
3. public static double distance(??) //returns the distance between two points
4. public static double slope(??) //returns the slope of the line determined by two
points
5. public static double intercept(??) //returns the y-intercept of the line determined
by two points
6. public static String printLine(??) //returns a String representing the equation of
one line "y = m*x + b"
All System.out.printlns should be placed in the main method and not the new
methods that you will be writing.
Part II: Documentation
Document your class, main method, other methods, and individual lines using both
multi-line comments and end of line comments.
Part III: Primitive Data Conversion
Copy and paste all of your code and comments from Part I into a file called
Points2.java.
Change the declaration of y0 and y1 in your main method only to int rather than
double. Without changing any of the methods or any other variable declarations, make
the changes that are necessary to get your program to compile and run. Initially, you
may have some compile errors due to narrowing conversions. Run your program. What
happened?
Write a slope2 method that accepts the x-coordinates as ints and returns an int.
Use this new slope method in your computation. Without changing any of the other
methods or any other variable declarations, make the changes that are necessary to get
your program to compile and run. Initially, you may have some compile errors due to
narrowing conversions. Explain what happens during the division. Does using the slope2
method increase or decrease accuracy of the computation from that of using the original
slope method? Why?
Write a slope3 method that accepts all coordinates as ints and returns a double.
Make sure that you do not perform integer division. Use this new slope method in
your computation. Without changing any of the other methods or any other variable
declarations, make the changes that are necessary to get your program to compile and
run. Initially, you may have some compile errors due to narrowing conversions. Explain
what happens during the division. Does using the slope3 method increase or decrease
accuracy of the computation from that of using the slope2 method? Why?
Print out your source code for Points2.java. Label all data conversions as assignment
(A), arithmetic (B), casting (C), parameter (D), or return (E) for the slope methods, the
distance method, the intercept method, and the main method. Also, label your
conversions as (W) widening or (N) narrowing. Hand your print out in (don't forget to
put your names on your work).
Part IV: Perimeter of a Triangle
Start a new class called Triangle.java. Obtain 3 points from the user. Write a method
(getPerimeter) to compute the perimeter of the triangle formed by those three points.
Call methods in the Points class as needed. Return the result to main and print out
the result in a complete sentence.
Post-lab:
Rounding
Examine the round method available in the Math class. Note that it will only round to
integer values. Suppose you needed to round a number off to a specified number of
decimal places. You need something more sophisticated than the round method
available in the Math class.
Write a Round class with a static method that accepts a double (call it val) and an int
(call it places) and rounds val off to the specified number of decimal places. The rounded
value (a double) is returned. If the specified number of decimal places is 0, your method
should behave the same as the Math.round method. That is, the double will be rounded
off to the nearest integer.
To get the extra functionality of specifying an arbitrary number of decimal places, you
could perform some initial computations (see the Math class) and then use the
Math.round method. However, it is possible (and better) to use a cast to an int to
achieve your goal rather than calling the Math.round method. Do this,
remembering that a cast to an int truncates the fractional part, so you might have to
think a little bit about how to make this work so that you get rounding rather than
truncation. Add a main method to your Round class to thoroughly test your
program. What happens if the number of places is negative? Again, your round
method will NOT use Math.round (or Math.floor, or Math.ceiling).
Use your Round method to round off the computed perimeter of your triangle to 2
decimal places.
Laboratory 4: Using Objects
Java API
Keyboard Documentation
Pre-lab:
Download the Keyboard class and place it in the directory where you will be working for
this lab.
Be comfortable with the methods available in the String class, the DecimalFormat
class, and the Random class. Know how to create objects of these classes and know
how to call their methods. Since most of the methods in these classes are not static, you
need to invoke their methods through a reference variable.
Lab:



String Class
o Pig Latin Translator
Random Class
o Abstraction
o Code Reuse
DecimalFormat Class
o Using Formatting Patterns
o Currency Pattern
Part I: Pig Latin
Write a program that accepts a word from the user. Assume that the word begins
with a single consonant. Transform the word into its pig latin equivalent. That is,
move the initial consonant to the end and then append "ay". For example, birthday
transforms to irthdaybay. Invert the transformed word to get the original word
back (don't simply use the original word).
Include the following static methods in your solution:
1.
2.
3.
4.
5.
public
public
public
public
public
static
static
static
static
static
String getMessage(String prompt)
String translate(String word) //translate to pig latin
String inverse(String word) //translate back
boolean standardEquals(String str1, String str2)
boolean aliasEquals(String str1, String str2)
Compare the original word obtained from the user to the word transformed to pig latin
and back in two ways:
1. compare them using the equals method (performed by standardEquals)
2. compare them using == (performed by aliasEquals)
Explain your results.
Part II: Random Numbers
import java.util.Random;
What if you want a random integer between 3 and 7, inclusive of both? There are no
methods in the Random class that will allow you to specify an arbitrary lower limit and
an upper limit. However, with a little extra work, the methods in the Random class can
be used to achieve a random integer between arbitrary limits. If you need arbitrary
limits often enough, the extra work required to obtain them using the methods in the
Random class can become very tedious.
You will now write some static methods in a new class (RandomNumbers.java) to do
this extra work. You will perform a simple calculation in each of your methods to ensure
the proper limits. Do not use any if statements or loops. From now on, when you
need arbitrary limits, simply use the methods that you are going to write in this lab. You
never need to concern yourself with the details required to achieve arbitrary limits ever
again. By doing this, you are abstracting, or hiding, the tedious details required to
include arbitrary limits from the Random class methods. This promotes code reuse as
you will use and reuse methods as you need them throughout your computer science
career.
Abstraction and code reuse are very important concepts in computer science which you
will revisit in most, if not all, of your computer science classes.
Include the following static methods in RandomNumbers.java:
1. public static double randomDouble(Random rand, int low, int high) (random
double between the given limits, low and high)
2. public static int randomInt(Random rand, int low, int high) (random integer
inclusive of the given limits, low and high)
Document this class in the usual way as it will come in handy later.
Part III: Formatting Numbers
import java.text.DecimalFormat;
Start a new class called RandomDriver and write the main method as follows. Obtain a
lower and an upper limit from the user. Using your work in Part II, obtain a randomly
generated integer and a randomly generated double using the specified lower and upper
limits. Display the randomly generated numbers using complete sentences. Format and
display the integer to include commas if necessary. Format and display the double to
show exactly two decimal places (and no commas). Display the formatted numbers
using complete sentences. Make sure that inputting the lower and upper limits as the
same value works correctly. What happens if low is greater than high? You will address
this in the post-lab.
Write a class (Currency.java) that contains the method shown below:

public static String formatCurrency(double val)
This method accepts a double and returns a String formatted for currency. That is, the
double is formatted to use a dollar sign, commas if necessary, and exactly two decimal
places. This is also an example of abstraction. Go back to RandomDriver and add some
code to the end of your main method to display your randomly generated double using
your new formatCurrency method.
Post-lab:
More Random and DecimalFormat
Fix up RandomNumbers so that a Random object does not need to be passed in to the
methods. To do this, look at the example on page 292 of your text concerning static
variables. You will create a Random object that can be used in any method in the
RandomNumbers class so it doesn't need to be passed in to those methods. Simply
create and declare a (static) Random object outside the methods in the
RandomNumbers class. This object can now be used in the two methods that you wrote,
so you don't need to pass them in any longer. Also, check that low is less than or equal
to high in your two RandomNumbers methods. If low is larger than high, set low to be
equal to high (use if statements).
Do the same procedure for Currency.java so that the DecimalFormat object is not
instantiated inside the method.
Write an application (PhoneNumbers.java) that creates and prints a random phone
number of the form XXX-XXX-XXXX. Include the dashes in the output. Do not let any of
the first three digits contain an 8 or a 9, and make sure that the second set of three
digits (taken together) is not greater than 742. Use your RandomNumbers class.
Don't copy code from RandomNumbers to PhoneNumbers.
To get the phone numbers to display properly, you will need two different formatters.
You may do all of your work in the main method of PhoneNumbers. Hint: each digit
does not have to be obtained separately.
Laboratory 5: Conditionals
Java API
Keyboard Documentation
Pre-lab:
Review boolean expressions, including expressions that make use of AND (&&) and OR
(||). Note that a boolean (the primitive data type) alone can be used represent a
boolean expression. Review conditionals, including the switch statement and nested
conditionals. In particular, note how conditionals have been used in class to check
input obtained from the user. You will also need to refer to various String methods.
Download the Keyboard class and place it in the directory where you will be working for
this lab. You will also need your work from the previous lab.
Lab:


If - Else If - Else
o Checking User Input
o Nested Conditionals
o Complex Boolean Expressions
Switch
Part I: If - Else If - Else
Modify your PigLatin program from the previous lab. Check user input to make sure that
the word contains at least 3 characters. If it doesn't, inform the user and quit. In
addition to handling words that begin with a single consonant, you will now allow words
to start with a vowel or two consonants. Thus, your program should work for words that
start with 0, 1, or 2 consonants. If the word begins with a vowel, simply append "yay" to
the end of the word (nothing is moved from the front to the back in this case). If the
word begins with two consonants, move both consonants to the end and append "ay" as
you did for a single consonant. Write and use the following method to determine if the
first or second letter of the inputted word is a vowel. Use the result of this method to
control your conditionals.

public static boolean checkVowel(char theChar)
Your program should also allow an inverse translation for the case that the word begins
with a vowel or a single consonant. If the word did not begin with a vowel, assume that
it began with a single consonant. You may also assume that the original word did
not start with a "y". Note any problems that are encountered when attempting to
write an inverse translation for the case with two constants.
Use one translate and one inverse method, the same methods that you wrote in
the last lab, but add conditionals to them.
Part II: Nested Conditionals &&/|| Complex Boolean Expressions
Write a program (BlackJack.java) to simulate a simple version of Black Jack. Generate
two random numbers (using RandomNumbers.java) in the range 1 to 13. Let a 1
represent an Ace and a 13 represent a King. Generate an if - else if - else statement
with no nesting and only using && to separately test for all possible combinations of
Black Jack. Limit the number of tests in each conditional to two (to avoid extremely long
boolean tests). Black Jack occurs when a player is dealt an Ace with a 10, Jack, Queen,
or King. Print out the numeric values of the cards drawn along with the text "Black
Jack!" or "No Black Jack." as appropriate. What is the maximum number of tests
that will ever be required in this format? Test your work. Why is it better to use if else if - else in this case rather than several separate if statements?
Rework your if statements to allow nesting and the use of ||. Reduce the number of
tests required as much as possible. Again, limit the number of tests in each conditional
to two (or less). Test your work. Why is this version more efficient?
Part III: Switch
Write a menu program (Menu.java) that allows users to select a salad, an entree, and a
dessert. Use the following choices and prices. If an invalid selection is made, make the
first choice the default choice. Format your menu selections using the escape sequence
for carriage returns to make your menu easy to read.



Salad
1. house salad $2.99
2. caesar salad $3.99
3. greek salad $3.24
Entree
1. chicken $4.99
2. steak $7.99
3. fish $5.79
Dessert
1. cake $2.99
2. ice cream $1.47
3. pie $2.64
Download Menu.java for the starting code for this part.
Complete the following methods :
1.
2.
3.
4.
public static String getSaladString() //create the menu text for the salad
public static String getEntreeString()
public static String getDessertString()
public static int getChoice(String prompt) //accepts a number between 1 and 3 for
a selection (if an invalid integer is inputted, set the choice to 1)
5. public static double getCost(int choiceSalad, int choiceEntree, int choiceDessert)
//uses a switch statement and all selections to compute the cost
After all the selections have been made, use the formatCurrency method in the
Currency class from the previous lab to display the total cost of the selections. Also
display the total cost without formatting. Find a combination of items that will not add
correctly to get the total cost, but contains a small error due to the fact that Java cannot
represent all floating point numbers exactly.
Post-lab:
Roulette
Write a program to play Roulette. Roulette is a wheel with 36 slots. A ball is spun in the
wheel and eventually stops in one of the slots. The slots are numbered 1 through 36.
Each number also has a color, red or black. Assume that even numbers are red and odd
numbers are black.
Allow the following bets to be selected from:
1. red or black (user enters "r" or "b")
2. first 12 (1 - 12), second 12 (13 - 24), or third 12 (25 - 36) (user enters "first",
"second", or "third")
3. a single number from 1 to 36
After selecting the desired type of bet by entering an integer in the range 1 to 3, the
user enters the specific bet as text rather than an integer, so use the readString
method even when an int is required from the user (as usual, check user input). You will
need the parseInt method of the Integer class. If an invalid entry is selected, inform
the user and quit.
If a valid entry is selected, generate a random number using the RandomNumbers class
and inform the user of a win or a loss (display the number generated, its color, and
whether it is in the first 12, the second 12, or the third 12). If the user wins,
compute the odds that they should be paid on their bet and inform them of their
winnings (you may assume that all bets are $1). For example, if the user matches a
single number, they should be paid 35:1 (a real casino will pay less than this to ensure a
profit), so they will win $35 if they bet $1. That is, there are 35 ways to lose, and 1 way
to win for this particular bet. Compute the odds that should be paid for the other bets
and pay the player the appropriate amount when they win.
Write methods as necessary to perform the various tasks.
Make up post-lab:
To make up a missed post lab (1-4), add some features to your Roulette program. Allow
the user to specify a starting bankroll. Let the user to continue playing until they want to
quit, keeping track of the bankroll balance. This involves computing the correct payout
for the bet when the user wins. Of course, you cannot bet more than you have (or a
negative amount). If the bankroll reaches zero, inform the user and quit.
Laboratory 6: Loops
Java API
Keyboard Documentation
Pre-lab:
Review while loops and for loops. Read about the do-while loop on page 242 in your
text.
Download the Keyboard class and place it in the directory where you will be working for
this lab. You will also need RandomNumbers from Lab 4.
You may also need to refer to various String methods.
Lab:


While Loop
o "Hiding" Nested Loops
o Do-While Loop
For Loop
Part I: While Loops
Write a program (Guessing.java) to play a simple guessing game. Select a secret
number between 1 and a constant MAX (set MAX in the first line of your program-- 100
is a good choice). Allow the user to pick a number in the range 1 to MAX. Inform the
user if they are too high or too low, and let them try again. If they guess the number,
inform them and tell them how many guesses it took to get the number correct.
Ask the user if they want to play again. If they do, select another secret number and
start all over. When they finally indicate that they do not want to play again, inform
them of the total number of games played, the total number of guesses for all games
played, and the average number of guesses per game.
Write the following methods (in addition to main):
1. public static int getGuess(final int MAX) //the user makes a guess with their guess
checked for the range 1 to MAX and return the guess (reprompt if not in the valid
range)
2. public static int playGuess(int secret, final int MAX) //user makes guesses and the
result is processed (higher or lower) until the guess is correct and the number of
guesses for this game is returned
In this way, the nested loops are "hidden" inside method calls. This makes the program
much easier to read and debug than it would be if all of your loops were done in the
main method. Test your work.
Part II: For Loops
Write a program (Palindrome.java) to test a word inputted by the user to see if it is a
palindrome or not. A palindrome is a word that is the same forwards and backwards.
Make sure that a single character and the empty string register as valid palindromes,
but don't write separate if statements to check for this.
Use a for loop to reverse the word, storing the reversed word. Write another for loop to
check for palindrome status by comparing the original String to the stored String
character by character. Use a boolean to store the result of the palindrome test.
Report the result (palindrome or not) using a conditional that branches based on the
value of the boolean. Don't use the .equals method in the String class.
Part III: Do-While
Rewrite your palindrome tester using do-while loops instead of for loops. Note any
problems that may occur and any assumptions that you need to make in order to use
this type of loop for this application.
Post-lab:
Grades
You will need to make use of a GradeBook object. Refer to the documentation for the
GradeBook class.
Write a program (Grades.java) to read in (from the keyboard) a list of final grades for
a class. Allow the user to keep inputting grades until the user inputs a sentinel value
(i.e. -1). You may assume the inputted grades are integer percentages from 0 to 100.
You may also assume that at least two grades will be entered. Compute and report the
average and the standard deviation with appropriate formatting applied. Using the class
average (c.a.) and the standard deviation (s.d.), report the number of A's, B's, C's,
D's and F's assigned to the class.
Compute the standard deviation as follows (Σ means summation, in this case, the
summation over all single final grades inputted):
1. sum = Σ(single final grade - c.a.)*(single final grade - c.a.)
2. s.d. = √ (sum / (n - 1)) where n is the total number of students
Once you have the class average and the standard deviation, compute the assigned
letter grade as follows:
1.
2.
3.
4.
5.
'A' final grade >= (c.a. + 1.5 * s.d.)
'B' final grade >= (c.a. + 0.5 * s.d.)
'C' final grade >= (c.a. - 0.5 * s.d.)
'D' final grade >= (c.a. - 1.5 * s.d.)
'F' final grade < (c.a. - 1.5 * s.d.)
Write the following methods:
1.
2.
3.
4.
public static GradeBook getGrades() //enter the grades into the GradeBook
public static double getAverage(GradeBook grades)
public static double getSD(GradeBook grades, double ca)
public static void countGrades(GradeBook grades, double ca, double sd) //count
the As, Bs, etc., and print the results to the screen
Laboratory 7: Writing Classes
Java API
Pre-lab:
Review visibility modifiers, get/set methods, constructors, object parameters, and
driver classes. Remember that System.out.printlns should be placed in the
driver class.
Download the Keyboard class and place it in the directory where you will be working for
this lab. You will also need your Currency.java file from an earlier lab.
Lab:







State variables
o integers
o booleans
o Strings
Visibility modifiers
o private state variables
o public get/set methods
o private helper methods
toString to report state
Controlling state changes with set methods
Driver class
Object parameters
UML
Part I: Ice Cream
Write an IceCream class (IceCream.java). Include instance/state variables for the
flavor, the number of scoops, whether a cone or a cup is desired, and a topping, if one is
desired. Write a default constructor to set reasonable default values of the state
variables. Write a toString method to report the current state of an ice cream object,
including the price of the entire order.
Also include the following methods:
1. public static String listFlavors() //list all the available flavors, at least five (why
static?)
2. public boolean setFlavor(String flav) //only certain flavors are available
3. public boolean setScoops(int scoop) //only 1, 2, or 3 scoops is allowed
4. public void setCone(boolean choice) //choices are cone or cup
5. public void setTopping(String top) //the topping can be anything
6. public double getPrice() //get the price of the ice cream cone
7. private boolean validFlavor(String testFlavor) //check that the flavor passed to the
setFlavor method matches one of the available flavors
An order of ice cream has a base price of $1.99. For each scoop (larger than 1), add
$.75. If a cone is requested, add $.59. Use currency formatting (remember the
principle of code reuse). The price of the order will be part of the reported state when
the toString method is called.
Note that some of your set methods will return a boolean to indicate whether the set
was successful or not. This is an excellent way to indicate to your driver class whether
the input from the user was valid or not. If it was not valid, your driver class needs to
get the requested input again. Also, your set methods will check to make sure that
a null is not passed to the method. Normally, you may assume that null is not
passed to a method.
Part II: Ice Cream Driver
As usual, your driver class interacts with the user, making changes to objects through
set methods as requested. Allow the user to order as many ice cream cones as they
wish. Write the following static methods which may need "hidden" loops to wait for
valid input from the user:
1.
2.
3.
4.
public
public
public
public
static
static
static
static
void
void
void
void
getConeChoice(IceCream ice)
getToppingChoice(IceCream ice)
getScoopsChoice(IceCream ice)
getFlavorChoice(IceCream ice)
After all selections have been made, report the state of the current ice cream order
(which includes the price, as noted earlier). Ask the user if they would like to order
another ice cream. Repeat the process until they don't want to order any more ice
creams. Report the number of ice creams purchased and the total price of the order.
Post-lab:
Enumerated Types
Investigate using an enumerated type to list the available flavors and to check that a
flavor was selected from the available flavors. See pages 135 and 316 for a discussion of
enumerated types. You will also need use a for each statement (see page 249-- we will
cover this in class in a few chapters). This is a form of the for loop which you can use to
automatically loop over all the flavors in your enumeration without a counter at all.
Example:
enum RB {red, black};
creates an enumeration called RB with valid values red and black. Note that red and
black are not Strings. Your enumeration should be an instance variable in your IceCream
class.
for (RB rb : RB.values())
loops over all of the values in the enumeration, storing each one in turn in the variable
rb. Note that rb refers to an object of type RB, so you can call the toString() method to
obtain the String representation of the enumeration. Thus, rb.toString() will either be
"red", or "black".
For more information, try here.
Laboratory 8: Overloading Methods
Java API
Keyboard Documentation
Pre-lab:
Review the concepts covered in the previous lab, as you will need many of them for
this lab as well. Review how to correctly compare floats. Review class level (static)
methods and variables.
Download the Keyboard class and place it in the directory where you will be working for
this lab.
Lab:







Reinforce
o Constructors
o Get/Set
o Encapsulation
Aggregation (HAS-A)
equals
this
Method Overloading
Static Methods and Variables
UML
Part I: Slope-Intercept Line
Download the Point class and place it in the directory where you will be working for this
lab.
Download the Line class and place it in the directory where you will be working for this
lab.
Complete the Line class. A Line is defined by two different Points. This means that two
Points need to be stored in the Line class. This represents an aggregate (HAS-A)
relationship. Write a constructor that accepts two Points as parameters. Be careful
not to violate encapsulation. If the Points are the same, set them to reasonable
default Points instead. Allow the constructor to compute and store the slope and
intercept of the Line as well. Overload the constructor to write a default constructor.
Have the default constructor call the constructor that takes two Points. Again, choose
reasonable default Points for the no argument constructor.
Write an equals method to compare two Lines within some tolerance. You will need
to think about how to do this. Write get methods for your instance variables. Make sure
that you do not violate encapsulation. Remember how objects and primitives differ
when they are method parameters or return values.
Write a class level (shared by all Line objects) intersection method to compute the
intersection of two Lines. The Point of intersection is returned by this method.
Overload this intersection method to compute the intersection between this and
another Line passed in as a parameter. Call the first intersection method within the
second, overloaded intersection method. To obtain the intersection of two Lines, you
need to set their equations (y = m*x + b) equal to one another and solve for x. Use the
equation (y = m*x + b) for either Line to obtain y once you have x.
Identify a local variable in the toString() method that can be made a class variable
(shared by all objects of the Line class), and make it one.
Part II: Parametric Line
A line can also be described by two Points in another, better way, called the parametric
equation of a Line. Use the following equation to obtain any Point on the Line, using
the two Points that define the Line and a parameter (α):
P(α) = (1 - α)*P1 + α*P2, where α is the parameter.
If α = 0, we obtain P1, one of the Points that describes the Line. If α = 1, we obtain P2.
If α is between 0 and 1, we obtain a Point in between P1 and P2 (a Point on the line
segment joining the two Points). Other values of α yield the rest of the Points on the
Line.
Write an evaluateParametric method that takes a value for the parameter and returns
the associated Point on the Line (use the above formula). Write an
intersectionParametric method to compute the intersection of this and another
Line passed in as a parameter and return the Point of intersection. A lot of algebra is
involved in obtaining the formula for the parameter of intersection, so the computation
of the parameter of intersection has been done for you.
Call the evaluateParametric method within the intersectionParametric method as
necessary. Overload intersectionParametric to accept two Points as parameters. Call the
first intersectionParametric method from within your overloaded method to compute the
intersection of this and the Line defined by the two Points passed in as parameters.
Part III: Intersection
Download the Intersection (driver) class and place it in the directory where you will be
working for this lab.
Complete Intersection.java. Display the inputted Points. Create two Lines from the
four Points, and display the equations of the two Lines. Compute and display the
intersection of the two Lines using both intersection techniques, calling all four
intersection methods (two overloaded intersection methods and two overloaded
intersectionParametric methods). Make sure that your results in all four cases are the
same.
Part IV: UML
Draw the UML diagram for Point, Line, and Intersection. Hand this in. For this and all
UML diagrams in later labs, you only need to show the class level relationships. You may
omit the method and instance variable sections of your UML diagram.
Post-lab:
Equal, Parallel, and Vertical Lines
Add the following methods to your Line class:
1. public boolean isParallel(Line other)
2. public boolean isVertical()
The basic equation of a Line, y = mx + b, has a major drawback. This equation cannot
handle vertical Lines as the slope of a vertical Line is infinity. If the Line is vertical, set
the slope and intercept to infinity. You will need to refer to the Double class to do this.
Modify your intersection method to return null if either Line is vertical, if the two Lines
are parallel, or if the two Lines are actually the same Line.
The parametric version of the line can handle vertical lines. Modify
intersectionParametric to return null only if the two Lines are parallel or are the same
Line. Verify that the parametric version will compute the correct intersection even if one
of the Lines is vertical.
Modify the toString method to report the equation of the line as x = constant if the
Line is vertical. Note that you will fill in the constant with an actual value.
Laboratory 9: Interfaces and Interface Type
Java API
Pre-lab:
You will be building on the work that you did in the previous lab. If you did the postlab, you should comment that work out. In this lab, you may assume that two Lines are
not vertical, parallel, or the same line.
Your work on the Line class in the previous lab actually handled two different ways to
view a Line simultaneously. The first view is the parametric view which relied on the
two Point instance variables. The second view is the slope-intercept view which relied
on the slope and intercept instance variables. Both have advantages and disadvantages.
The parametric view handles vertical lines automatically. The slope-intercept view is
more familiar to most people. Thus, it makes sense to have both available. However,
typically one form of a Line or the other will be used by an individual class. Having a
class handle both simultaneously is clumsy, as evidenced by the clumsy method names
that you had to use in the previous lab.
You will create two implementations of a Line. In many cases, the user is not interested
in the implementation details. That is, they do not care if the parametric view or the
slope-intercept view is being used to create the Line. They just need to know how to use
the Line. An interface allows you to provide multiple implementations, but to hide the
implementation details. Thus, we encounter the principle of abstraction once again. All
the user needs to know about is the methods that they need to call to get their work
done. However, in those cases that the exact implementation is important (for example,
cases where vertical lines must be easily handled), the actual implementation exists and
can be specifically requested.
Lab:




Interfaces
Separate Implementations of a Common Interface
o Parametric Line
o Slope - Intercept Line
Hiding Implementation (Abstraction)
o Interface Type
o Factories
More UML
Part I: Multiple Line Implementations Using a Common Interface
Write an interface (LineInterface.java) that contains the following method signatures:
1. public Point intersection(LineInterface other)
2. public Point evaluate(double x) //x is either the parameter or the x-coordinate
Note that an interface type is passed as a parameter. This has very important
consequences. In particular, you will be able to compute the intersection of two Lines
even if one is implemented with the parametric view and the other is implemented with
the slope-intercept view. Just use the methods provided in the interface to accomplish
your task. In fact, even if you wanted to, you could not easily access methods not
present in the interface because you don't know from what class the object is created.
You only know that it implements LineInterface.
Break your work on the Line class from the previous lab into two new classes:
1. LineParametric
2. LineSlopeIntercept
LineParametric will only contain the two Point instance variables. The two Points will
be passed to the constructor (remember encapsulation). Implement the interface using
only the two Points to perform the calculations. Modify the toString method to display
the parametric equation of a Line. See the previous lab. Provide get methods for the
two instance variables (remember encapsulation).
LineSlopeIntercept will only contain the slope and the intercept as instance variables.
The slope and intercept will be passed to the constructor. Implement the interface using
only the slope and the intercept to perform the calculations. You may find it
necessary to write some private helper methods. The toString method should
display the equation of the line as done in the previous lab. Provide get methods for the
instance variables.
Part II: Using an Interface Type
Write a driver (LineDriver) to instantiate both a LineParametric and a
LineSlopeIntercept. It is not necessary to make your driver interactive. Often when you
are testing your work, you simply "hard-code" values into your program. That is, instead
of asking for the x and y coordinate for a Point from the user, you simply create one
with an x and y coordinate of your choosing. Your code in your driver class might look
like this:
LineParametric line = new LineParametric(new Point(3, 7), new Point(5, 19));
Display both of the lines. Evaulate the lines at various locations. Compute their
intersection twice, one time with the LineParametric as the calling object, and one time
with the LineSlopeIntercept as the calling object. Call the respective get methods. Make
sure that all of your results are correct.
Now change the type of both of your lines to LineInterface. For example:
LineInterface line = new LineParametric(new Point(3, 7), new Point(5, 19));
What happened when you tried to compile? Why? Fix this while leaving the type as
LineInterface and without removing any of the code in your driver. This makes it
inconvenient for the user to call methods not in the interface. When you use an interface
type, you typically don't care about the implementation, so you will only call the
methods in the interface. Remove any calls to methods not in the interface.
Part III: A Line Factory
You can do more to ensure that it will be very unlikely that the user will be able to call
methods not in the interface. You will be taking the idea of abstraction even further.
Instead of providing the option of abstraction through the use of an interface type, you
will be forcing the idea of abstraction on your users. This is important because it
allows other programmers to use your interface to design their code, even if
the actual implementations for a given interface haven't been written.
Write a class (LineFactory.java) that contains two static, overloaded methods called
createLine. Depending on which overloaded method is called (which depends on the
parameters given to the method), instantiate and return the appropriate line
implementation. However, make the return type of both of the static methods be
the interface type, LineInterface.
Modify your driver to use the factory methods to create the lines. Note that the new
keyword is never directly used in the driver. It is "hidden" inside the factory. The user
does not have to use the actual class name at all to obtain their line, which is a detail
about how the line is implemented that they generally don't care about anyway. If they
wanted to call methods not in the interface, it would be a bit of trouble for them to do
this, as they would have to figure out what the names of the classes are.
Part IV: UML
Draw the UML diagram for Point, LineInterface, LineSlopeIntercept, LineParametric,
LineFactory, and LineDriver. Hand this in.
Post-lab:
Packaging and Default Visibility
Look on the Internet for resources concerning packaging in Java and default visibility.
Try here for starters (look at the post-lab). In particular, look at the step by step
instructions. Not all of the steps will apply.
You can still do more to ensure that the implementations behind an interface are not
directly instantiated. Instead of public classes, you will need to change the visibility of
your two Line implementations to default visibility (omit a visibility modifier for a
particular class altogether). Don't change the visibility of particular methods,
however. LineFactory, LineInterface, and Point will still retain public class visibility. You
can then "package" all the related Line classes together (the factory, the interface, the
two implementations, and Point, but not LineDriver). What this procedure does is allows
the classes in the package to instantiate one another (i.e. the factory class needs to
instantiate the various implementations), but outside users cannot directly instantiate
the implementations. They must go through the public factory class. Even if they
somehow knew the class names for the implementations, it does the user no good.
Laboratory 10: Object Arrays and ArrayList
Java API
ArrayList Documentation
Lab 10 Documentation
Pre-lab:
You can find the rules of blackjack all over the Internet. To get an idea of what you are
trying to accomplish in this lab, play my version of BlackJack. The dealer stands on all
17s. Doubling after splitting is always allowed. Multiple splitting is always allowed.
The yellow highlighting is the optimal decision given your cards and the dealer's up card.
Refer to the table below for the complete optimal strategy for blackjack. Across is the
dealer's up card (T means a 10 or any face card). Down is your hand value. S means
stand in that situation, H means hit, D means double down, and P means split (which is
only relevant at the bottom of the table where the possible duplicate card values are
listed). Note that the A/ entries represent soft hands of two or more cards.
The row refers to the row in the strategy array (see BlackJackPlayer) where the
desired move for that hand total can be found. After the row has been determined by
the hand total, simply go to the column corresponding to the dealer's up card. Note: the
hand totals begin with 2 (two aces) and go up to 21.
Download BlackJack.exe. This executable contains a lot of the files that you need to
run BlackJack but don't need to modify. For example, the card images are stored here.
Put the executable in the directory where you will be working for this lab. When you
think that you have completed the lab, run the executable and check for bugs. The
executable will not run until all of the classes that you need to work on below have been
compiled. Note that splitting will not work unless you have completed the postlab.
Dealer's Up Card
2 3 4 5 6 7 8 9 T A
<= 8 (row 0 - 6)
H H H H H H H H H H
9 (row 7)
H D D D D H H H H H
10 (row 8)
D D D D D D D D H H
11 (row 9)
D D D D D D D D D H
12 (row 10)
H H S S S H H H H H
13 (row 11)
S S S S S H H H H H
14 (row 12)
S S S S S H H H H H
15 (row 13)
S S S S S H H H H H
16 (row 14)
S S S S S H H H H H
>= 17 (row 15 - 19)
S S S S S S S S S S
A/2 (row 20)
H H H D D H H H H H
A/3 (row 21)
H H H D D H H H H H
A/4 (row 22)
H H D D D H H H H H
A/5 (row 23)
H H D D D H H H H H
A/6 (row 24)
H D D D D H H H H H
A/7 (row 25)
S D D D D S S H H H
A/8 (row 26)
S S S S S S S S S S
A/9 (row 27)
S S S S S S S S S S
A/10 (row 28)
S S S S S S S S S S
2/2 (row 29)
P P P P P P H H H H
3/3 (row 30)
P P P P P P H H H H
4/4 (row 31)
H H H P P H H H H H
5/5 (row 32)
D D D D D D D D H H
6/6 (row 33)
H P P P P H H H H H
7/7 (row 34)
P P P P P P H H H H
8/8 (row 35)
P P P P P P P P P P
9/9 (row 36)
P P P P P S P P S S
10/10 (row 37)
S S S S S S S S S S
A/A (row 38)
P P P P P P P P P P
Refer to the ArrayList class as necessary.
Lab:






Reinforce
o Constructors
o Loops
Randomizing Object Arrays
For-each statement
Object Arrays as Parameters/Return Values
ArrayList
Primitive Arrays
o 1D
o 2D
Part I: Decks of Cards
Download the Card class. You will need the Picture class to compile Card.java (but
there is no work required in this file). Note that the compareTo method will compare by
face value first, then by suit. Thus, a sorted Deck of Cards will have all the Aces first in
the order Spades, Hearts, Clubs, Diamonds. Then the 2s in the same suit order, and so
forth.
Complete the constructor in the Decks class. Create the requested number of standard
52 card decks (check user input). You will need to use a nested for loop. After you have
all the required Cards, shuffle all of the of Cards together.
Complete the shuffle method in the Decks class. Use a for-each statement and your
RandomNumbers class. After all of the Cards are shuffled, reset count so that all of the
Cards in the Decks are again available.
Look at the deal method (the code for this method has been given to you). The deal
method uses the count instance variable to return the next Card in the Decks. After a
Card has been selected from the Decks, count is decremented in preparation for the
next call to deal. If there are no more Cards left to deal, shuffle is called to reset the
Decks.
Part II: BlackJackHand
Complete the BlackJackHand class. A BlackJackHand object holds a minimum of two
Cards, but the maximum number that the hand will hold is not known. Thus, it is
convenient to use an ArrayList to hold the Cards in the BlackJackHand. Make your
ArrayList able to hold only Card objects. The constructor will accept two Cards, which
are placed in the ArrayList. You must also determine whether the hand is a soft hand or
not. Simply determine if one of the two Cards is an Ace, in which case the hand is soft.
The remaining methods that you need to complete are described in the comments.
Part III: BlackJackPlayer
Complete the BlackJackPlayer class to obtain the desired move given a player's hand
total and the dealer's up card. You will also need the FileIO class to compile
BlackJackPlayer.java (but there is no work in this file). The desired strategy is read in
from a text file and stored in a 2D integer array (done for you). Use the row and column
information provided above to determine the optimal strategy. Your result will be
highlighted in yellow when the game is running. The user is not required to use the
optimal strategy, however.
Post-lab:
Splitting
Complete the methods in BlackJackHand and BlackJackPlayer relevant to splitting.
Make-Up Post-lab:
Matrix
To make up a missed post lab (5-9), modify BlackJackPlayer.
Write a new class called BlackJackPlayerMatrix. BlackJackPlayerMatrix will use the
matrix package instead of a 2D array. Your instance variable will be type
BasicMatrixInterface. You will need to use an import statement. Refer to the
documentation for the Matrix classes.
The MatrixCreator class has one static method needed to obtain a matrix:
public static MatrixOperationsInterface create(int rows, int columns)
Laboratory 11: Inheritance Hierarchies
Java API
Pre-lab:
Review inheritance, abstract classes and methods, etc. Review Comparable and using an
interface and an inheritance hierarchy together. Refer to the examples below for a
sample bibliography containing all of the different types of citations.

















[1] Prince, Dinah. "Marriage in the '80s." New York 1 June 1987: 30-38. (paraphrase)
o A magazine citation with a single author. The name of the periodical is New York, and the date of the issue is 1
June 1987.
[2] Booth, Wayne, et al. "Kenneth Burke's Way of Knowing." Critical Inquiry 1 (1974): 1-22. (direct quote)
o A journal citation with multiple authors. The name of the journal is Critical Inquiry, the volume number is 1.
[3] Fairbanks, Carol. Prairie Women: Images in American and Canadian Fiction. New Haven: Yale UP, 1986. 325-327.
(direct quote)
o A book citation. New Haven is the city of publication. The publisher is Yale UP (University Press).
[4] Baum, Rosalie. "Alcoholism and Family Abuse in Maggie and The Bluest Eye." Mosaic 19.3 (1986): 91-105. (paraphrase)
o Another journal citation. Note that this citation has a volume number of 19 and an issue number of 3. Here is a
good place for the use of a convenience constructor to provide an issue number.
[5] Quirk, Randolph, et al. A Comprehensive Grammar of the English Language. London: Longman, 1985. 11-19.
(paraphrase)
o Another book citation.
[6] Gordon, Alan, et al. Humanistic Scholarship in America. Proc. of the Conference on the Princeton Studies in the
Humanities. 5-6 Nov. 1965. Princeton: Princeton U, 1966. 499-502. (paraphrase)
o A proceedings citation with multiple authors. Note the name and date of the conference.
[7] Winks, Robin, et al. "The Sinister Oriental Thriller: Fiction and the Asian Scene." Mosaic 19.3 (1986): 49-61.
(paraphrase)
o Another journal citation. Note that this journal appears earlier. Use a convenience constructor to pass in the earlier
journal so that the repetitive information is easily obtained.
[8] Ferrara, Jerry, et al. "Why Vultures Make Good Neighbors." National Wildlife June - July 1987: 16-20. (paraphrase)
o Another magazine.
[9] Reger, Zita, et al. "The Functions of Imitation in Child Language." Applied Psycholinguistics 7 (1986): 323-352.
(paraphrase)
o Another journal.
[10] Morrison, Tim. Humanistic Scholarship in Europe. Proc. of the Conference on the Princeton Studies in the Humanities.
5-6 Nov. 1965. Princeton: Princeton U, 1966. 99-104. (paraphrase)
o A proceedings citation that uses an earlier proceedings.
[11] Hansberry, Lorraine. A Raisin in the Sun. Black Theater: A Twentieth Century Collection of the Work of its Best
Playwrights. Ed. Lindsay Patterson. New York: Dodd, 1971. 221-276. (paraphrase)
o An anthology citation. New items include the name of the work inside the anthology and the name of the editor.
[12] Walsh, John. "U.S. - Japan Study Aim Is Education Reform." Science 16 Jan. 1987: 274-275. (paraphrase)
o Another magazine.
[13] Gilbert, Sandra, et al. Acts of Attention: The Poems of D. H. Lawrence. Ithaca: Cornell UP, 1972. 11-19. (direct quote)
o Another book.
[14] Lazard, Naomi. In Answer to Your Query. The Norton Book of Light Verse. Ed. Russell Baker. New York: Norton, 1986.
52-53. (paraphrase)
o Another anthology.
[15] Ferrara, Jerry, et al. "The Mysterious Platypus." Science 16 Jan. 1987: 77-78. (paraphrase)
o Another magazine that uses an earlier magazine.
[16] Truman, James, et al. The Light Fantastic. The Norton Book of Light Verse. Ed. Russell Baker. New York: Norton, 1986.
102-105. (paraphrase)
o Another anthology that uses an earlier anthology.
[17] Gilbert, Sandra, et al. Acts of Attention: The Poems of D. H. Lawrence. Ithaca: Cornell UP, 1972. 22-24. (paraphrase)
o Another book that uses an earlier book with different page numbers.
Lab:


Inheritance
o extends
o super
o protected
o abstract classes and/or methods
o overriding and overloading
 equals
 constructors
o implements
o indirect
Reinforce
o Comparable Interface
o Get Methods
Part I: The Parent Class
For this lab, assume all instance variables have private visibility except for boolean
multiple (see later). It is up to you to determine where abstract classes and methods
should be used in the following description of the Citation Hierarchy. You should use
abstract somewhere. Also, don't write any set methods in this lab. Instance variables
can only be set through constructors.
Write a class called Citation. As the parent class, Citation stores the elements of a cited
work that are common to all possible Citations (but Citation may not represent a real
Citation on its own). Citation stores the citation number (corresponding to the order that
the citation appears in the associated paper, check user input) and whether the citation
is a direct quote or a paraphrase. Citation also stores a boolean (multiple) that can be
used to indicate whether the Citation requires special formatting for several authors or
not (et al.). You will give the multiple indicator visibility such that it is directly available
to subclasses only (protected visibility). Do not write a get method for multiple, use
it directly when needed, and set it directly in the child constructors. A need for
special formatting for several authors is common to all Citations. What does this fact
imply about the author information? Make sure to store the first name and last name
separately. What else, if anything, could be placed in Citation? So that your hierarchy is
consistent with mine, use the following Citation constructor (additional Citation instance
variables are possible, but place them in the child classes):
public Citation(int citeNum, boolean quote, String authorLastName, String
authorFirstName, int startPage, int endPage)
//remember, multiple should be accessed directly in the child classes
Write a protected method (endCitation) method to return a String with the starting
and ending page numbers and the text "(direct quote)" or "(paraphrase)" that will be
added to the end of a citation. As the starting and ending pages and the text direct
quote/paraphrase must appear at the end of the citation, this part cannot be prepared in
the Citation class but must be appended in the child classes when appropriate.
Write a protected method (startCitation) to return the start of a citation correctly
formatted. Write a public method citation to return the entire correctly formatted
Citation. However, in the Citation class, the citation method can only prepare the start
of the citation. The child classes will be responsible for making sure that the entire
citation is correct for the particular work being cited. Use super wherever appropriate.
Allow Citations to be compared by citation number (for sorting-- you need to
implement an interface). Write two non-static equals methods. The first will override the
equals method inherited from Object (and will call the second equals method). The
second will overload the equals method to compare two Citations based on the citation
number. Use your method for comparing citations to perform the test for equality. You
will be comparing Citations in the next lab.
Part II: The Child Classes
Complete the hierarchy given the following class names, in no particular order:






Proceedings (a collection of papers corresponding to talks given at a conference
bound into book form)
Periodical (any publication that appears regularly at fixed intervals)
Anthology (a collection of works bound into book form)
Journal (published at regular intervals)
Book
Magazine
Each subclass should have overloaded constructors as needed that call one another. In
particular, provide a convenience constructor for Citations that have several items in
common with other Citations. For example, suppose that you need a citation for a given
Book for pages 12-14 and another citation for the same Book but pages 64-65. It would
be convenient to have a Book constructor accept another Book as a parameter so that
all the elements in common can easily be placed into the new Book citation without the
user having to specify all of the details again. Do the same for other subclasses as
necessary. Also, note the use of issue in some cases for the Journal citations. Refer to
the driver class below to determine the order that items should be accepted by
your constructors.
Your hierarchy should have at least three levels where Citation is the parent
class to all of the other classes and counts as level 1.
Part III: CitationDriver
Test your hierarchy with CitationDriver. You should obtain the output shown in the
pre-lab.
Part IV: UML
Draw the UML diagram for your Citation hierarchy and your CitationDriver. Include the
Comparable interface in your diagram. You may omit the method section. Hand this in.
Post-lab:
Website Citations
Websites are commonly used as sources in research papers. Find out how websites are
cited here. Add a Website branch into your hierarchy. Start your Website branch with
an abstract Website class that extends Citation. Include the following instance
variables in your Website class:
1. private String siteTitle;
2. private String dateAccessed;
3. private String url;
Extend this abstract class as much as necessary to do the job right.
Add Website citations to your driver. Test all of your new concrete (i.e. non-abstract)
classes. Make sure that the resulting output is correct.
Laboratory 12: Collection Polymorphism
Java API
Pre-lab:
Review polymorphism for both inheritance hierarchies and interfaces. Review the foreach statement. You will be building on your work in the previous lab.
Refer to the ArrayList class as necessary.
Lab:



Polymorphism
o Inheritance Polymorphism
o Interface Polymorphism
Reinforce
o Comparable Interface
o ArrayList
o for-each
o Set Methods
Testing
Part I: Bibliography
Write a collection class (Bibliography.java) that encapsulates an ArrayList to store an
unspecified number of any type of Citation. Write an add method that will accept a
Citation and will return a boolean. Will this method allow you to add all of the different
types of Citations? Inside the add method, the Citation object passed in is added into the
ArrayList so that the items are stored in increasing citation number order even if
they are not added to the Bibliography in that order. Do not use a sorting algorithm
but rather find the correct insertion location for the item when it is added to the
Bibliography. Do not use a get method to determine the insertion location. Do you
need to cast to keep the citations in citation number order? Do not allow a citation to
be added if there is already one in the Bibliography with the same citation
number. Use the equals method in Citation to determine if there already is a Citation
with that number in the Bibliography. Do you need to cast to check for equality? Return
true if the insertion is successful and false otherwise. Have your add method filter out
Periodicals so that they are not inserted into the Bibliography.
Write a bibliography method to return the entire set of bibliographic citations in the
order that they are stored in the ArrayList (return a String). Use a for-each statement.
Do you need to cast to create the bibliography? Write a helper method to renumber the
citation numbers (you will need to add a set method to the Citation class) to close any
gaps in the numbering, if there are any gaps. Call this helper method just before
generating the bibliography.
Overload the add method to accept a Comparable. Call the other add method from
within this method to actually perform the addition, however. Can you use this add
method to add your Citations?
Part II: CitationDriver
Write a driver (CitationDriver) to test your Bibliography. Insert all of your Citations into
a polymorphic array of type Citation[]. You may use the same Citations from the
previous lab with any modifications required to use your polymorphic array. That is,
start with CitationDriver. Write the following two static methods in CitationDriver:
public static void add(Bibliography bib, Citation[] cites) //attempt to insert all of
the Citations from your array into the Bibliography-- use a for-each statement
public static void add(Bibliography bib, Comparable comp) //attempt to insert a
single Comparable into the Bibliography


Print to the screen whether an insertion was successful or not (simply print the value
returned from the Bibliography add method). Temporarily give the Bibliography add
method that takes a Citation private visibility. Does your driver still work? Why?
Comprehensively test your Bibliography implementation. Add citations in unsorted order
(add citation 7, then 4, then 27, etc.). Make sure that any gaps in citation numbering
are closed. Make sure that duplicate citation numbers are not added. Make sure that
Periodicals are filtered out. Make sure that you can add Citations through the add
method that takes a Comparable (how do you do this?). Make sure that Comparables
that are not actually Citations are filtered out (use the CD class to do this test).
Download TestDriver.class, Debug.class, and CD.class (which is used in TestDriver).
Run TestDriver. You should obtain the following output:
true
true
true
true
false
true
true
true
true
false
true
true
true
true
false
true
false
true
true
true
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
original number, 1.
original number, 2.
original number, 3.
original number, 4.
original number, 5.
original number, 10.
original number, 12.
original number, 14.
original number, 17.
original number, 20.
[11]
[12]
[13]
[14]
[15]
[16]
original
original
original
original
original
original
number,
number,
number,
number,
number,
number,
24.
25.
27.
31.
32.
50.
When you get this output, you are done with this part.
Part III: UML
Modify your UML diagram from the previous lab to include Bibliography. Make any other
modifications that are necessary to describe the relationships of your classes in this lab.
You may omit the method sections. Hand this in.
Post-lab:
Remove and Iterator
Write a remove method which takes a citation number as a parameter. Look for that
number in your Bibliography. If it is found, remove it and return true. Otherwise, return
false. Test your work.
Along with the Comparable interface, there is another useful built-in interface in Java,
the Iterator interface (import java.util.Iterator;). This interface is important for "looping"
over all of the items in a collection, such as all of the Citations in your Bibliography. In
fact, the for-each statement really uses the Iterator interface behind the
scenes. Modify your bibliography method in the Bibliography class to use an Iterator
instead of the for-each statement. Simply call the iterator() method on your ArrayList to
obtain the Iterator for the ArrayList. Once you have the Iterator, you may use the
methods available to loop over all of your Citations. Typically a while loop is used with
an Iterator. The Iterator interface has the following methods:



public boolean hasNext() //are there any more Objects to process?
public Object next() //get the next Object
public void remove() //you don't need this one
Laboratory 13: Exception Handling and File I/O
Java API
Pre-lab:
Review exceptions and exception handling. In particular, review how checked and
unchecked exceptions must be treated differently. Review file I/O including writing
objects to a file.
Lab:


Exceptions
o Custom Checked Exceptions
 Throwing Exceptions
 Error Messages
 Additional Information
o Handling Exceptions
File I/O
o Text Files
o Serializing Objects
Part I: Custom Exception
Create a custom checked exception (CitationException) similar to the class examples
initially. Add a Citation instance variable. Overload the constructor to accept an error
message and a Citation object. Have the first constructor call the second. What should
be the second parameter? In the second constructor, copy the Citation object into the
instance variable. Add a method (getProblemCitation) to return the Citation object
associated with the error message.
Modify the Citation hierarchy as necessary to throw a CitationException if the citation
number is <= 0. You could (not required) also check to make sure that nulls have not
been passed in as arguments to the Citation constructor. You will need to use the single
parameter constructor in CitationException as no Citation object has been created. Use
an appropriate error message for each problem that you check for. What would change if
you had made CitationException an unchecked exception?
Part II: Propagating and Handling Exceptions



Book
Proceedings (a collection of papers corresponding to talks given at a conference
bound into book form)
Anthology (a collection of works bound into book form)
Allow Periodicals to be added to your Bibliography. Modify Bibliography to throw an
exception if a duplicate citation number is detected. The add method can be void as we
are using exceptions to identify the user of problems rather than a boolean. Also have
Bibliography throw an exception if gaps are detected when the bibliography method is
called. Use a helper method to determine if gaps are present. Do not renumber as you
did in the previous lab. It is best not to assume how the user wants to handle a given
problem. Use the CitationException constructor that allows you to store the Citation that
caused the problem.
Modify your driver from the previous lab to report any errors detected. Structure your
try-catch blocks so that no additional processing is done once a problem has been
detected. Display the Citation that caused the problem (by calling the citation method)
when one is available. Test all possible errors (create errors as needed) to make sure
that you are correctly handling all of the exceptions and reporting all of the correct
information in each case. When you are sure that everything is working, take the errors
out and move onto the next part.
Part III: File I/O
Complete the following methods in Bibliography (you will need to rethrow exceptions):
1. public void writeToFile(String fileName) throws CitationException //writes the
bibliography out to a text file (i.e. bib.txt)
2. public void writeToDisk(String fileName) throws CitationException //writes the
ArrayList encapsulated by the Bibliography object out to a file (i.e. bib.dat)
3. private static ArrayList readFromDisk(String fileName) throws CitationException
//reads an ArrayList in from a file
The third method is called from an overloaded constructor that accepts a file name to
instantiate a Bibliography object based on the information stored in the file.
At the end of your try-catch in your driver, add code to save your bibliography to a text
file and to save your ArrayList to a file. In a separate try-catch, instantiate a new
Bibliography based on the saved ArrayList and print the resulting bibliography out to a
text file. Make sure that the two text files are not empty and have identical
contents.
Check everything with TestDriver.
Here is the output that you should obtain. Your error messages will be different, but
should convey the same information.
The citation number must be greater than 0.
Duplicate citation number encountered.
[3] Hansberry, Lorraine. A Raisin in the Sun. Black Theater: A Twentieth Century
Collection of the Work of its Best Playwrights. Ed. Lindsay Patterson. New York: Dodd,
1971. 221-276. (paraphrase)
Gap found in bibliography.
[55] Gilbert, Sandra, et al. Acts of Attention: The Poems of D. H. Lawrence. Ithaca:
Cornell UP, 1972. 22-24. (paraphrase)
In addition, the text files out.txt and test.txt should be exactly the same.
Post-lab:
Abstracting ArrayList Serialization
Above, you wrote code to read and write an ArrayList of Citations to and from disk inside
Bibliography. This is not ideal as you will need to use the same code with slight
modifications in future programs to process ArrayLists. It is much better to abstract this
process into a new class that can be used whenever you need to process ArrayLists.
Write a class (SerializeArrayList) that will provide methods to read and write any
ArrayList to and from disk. Include the following methods:
1. public static ArrayList readFromDisk(String fileName)
//returns null if a problem occurs
2. public static int writeToDisk(String fileName, ArrayList al)
//returns -1 if a problem occurs
Modify Bibliography to use your new class. Test your work.
More Object Serialization
Sometimes your objects contain sensitive information that you don't really want to save
to disk when you serialize those objects. Find out how to keep a field from being saved
during object serialization (hint: look at page 685). Keep the author's last name from
being saved to disk. Rerun your driver. What happened?
Laboratory 14: Graphics and GUIs
You may need the following Java API links:




Entire Java API
Graphics Class
Timer Class
MouseListener Interface
Pre-lab:
Review Graphics and GUIs.
In this lab you will be modifying some existing code to create a moderately complex
graphical scene that responds to mouse events. You are provided with a Shape
hierarchy, a Tree class (and its component classes), a Car (yes, it's really a bus) class
(and its component classes), and a JFrame subclass, DrawCanvas, to render the scene.
Compile DrawDriver and run the program (download all the files below into the same
directory). Use make.bat for compiling and running as the classpath must be modified to
use matrix.jar (for complex transformations of objects in the scene). Click inside the
window to start the car moving across the scene. Double click on DrawDriverFinal to see
what you are trying to accomplish in this lab.
Starting files:






















Get them all in a zip file
Visual.java
Shape.java
Rectangle.java
Square.java
Ellipse.java
Circle.java
Trunk.java
Branch.java
Leaves.java
Tree.java
CarBody.java
Wheel.java
Car.java
DrawDriver.java
DrawCanvas.java
Picture.class
RGBA.class
matrix.jar
make.bat
background.raw
DrawDriverFinal.exe
Lab:



Reinforce
o Has-a Relationship
o Is-a Relationship
o Object Arrays
o Interfaces
Basic Graphics
o Shape Hierarchy
o Visual Interface
o Graphics class
Basic GUIs
o Mouse Events
o Timer
o repaint
Part I: Creating a Forest
Write a class called Forest. Implement the Visual interface to guarantee a visual
behavior for your forest object. Write a constructor to allow the user to specify the
number of trees in your forest. Allow the user to also specify the max and min x and y
values for the horizontal center and base of the trees in the forest (you will need to refer
to the Tree class). Finally, the user can specify the max and min width and height of the
trees in the forest, and the max and min angles for the branches. Generate the number
of trees specified, with randomly generated locations, sizes, and angles based on the
ranges specified. Loop over the trees (use a for-each statement), drawing them in your
draw method. Add your forest to the scene (in DrawDriver), and modify the ranges to
generate a forest for your scene. Make sure that the car is rendered on top of your
forest.
Part II: Creating a Face
Write a class called Face. Extend Circle and use inheritance to draw a face with eyes
and a smile. Add a face to the Car class as an additional component (the driver of the
car). Include the rendering of the face in the draw method of Car. Modify parameters as
necessary to get the driver in the window of the car. You will need to add a move
method to the Face class so that as the car moves, the face will move with it.
Post-lab:
Mouse Events
Modify your DrawCanvas class so that when the mouse is pressed in the scene, the
animation begins (already done for you). If the mouse is pressed again, the animation
ends. If the mouse exits the scene, the smiley face turns to a frowny face. If the mouse
enters, the smiley face returns. You will need to add a change method to some classes,
and provide an alternate rendering of the face as necessary.
Make-Up Post-lab:
Be Creative
To make up a missed post lab (10 - 13), do the following. Make some additions and/or
modifications to this lab. You may do anything that you want as long as it involves some
Graphics or GUI feature that has not been covered in this lab, has not been covered in
class, and isn't a trivial change.
Download