Copyright © Cay S. Horstmann 2009 
This work is licensed under a Creative Commons
Attribution-Noncommercial-Share Alike 3.0 United States License.
In this lab, you will work in groups of two.
Put the answers to the questions in each step into the lab report. Copy/paste the programs that you write in the lab.
This icon indicates optional tasks. Do those if you have time.
Drawable InterfaceCar,
CarViewer, CarComponent from chapter 3.
Modify the program so that it can draw an arbitrary number of cars:
private ArrayList<Car>
cars paintComponent method with a loop that draws
all cars in the array list CarComponent constructor, fill cars
with five cars with different locationsRun your program to check that it draws the cars. Attach the source code to your lab report.
House class to your
project. Modify the CarComponent class so that it also draws
houses:
private ArrayList<House>
houses paintComponent method, add a loop that draws all
houses in the array list CarComponent constructor, fill
houses with five houses with different locationsRun your program to check that it draws the cars and houses. Attach the source code to your lab report.
CarComponent class to SuburbanScene.
(Note for Spring 2010: Update to use Netbeans and show off refactoring)
public void draw(Graphics2D g2)
Make an interface Drawable that declares a single method
draw. Make Car and House implement
that interface.
Compile and run your program to make sure it still works.
Car and House (and potentially other classes)
implement a common interface. Change the CarComponent (or, if
you renamed it, SuburbanScene) as follows:
drawables that holds Drawable objectspaintComponent method so that it draws the
elements of drawables. Car and
House objects to the drawables array. Run your program to check that it draws the cars and houses. Attach the source code to your lab report.
paintComponent method again. It should contain
code similar to
for (Drawable d : drawables) d.draw(g2);
How does the compiler know that d (or whatever you called
it) has a draw method?
drawables.add(new Car(30, 40));
But drawables is not an
ArrayList<Car>. It is an
ArrayList<Drawable>. Why is it legal to add a
Car?
Ball that also implements the
Drawable interface. Its draw method should call
g2.setColor(Color.RED); g2.fill(new Ellipse2D.Double(x, y, DIAMETER, DIAMETER)); g2.setColor(Color.BLACK);
Add a few balls to the drawables array list.
Attach the code for all classes to your lab report.
Dog class for an example. You also
need this image in the same directory. Add some dogs
to your scene.

(I mention this here because this kind of thing may be useful for your final project.)
private static Random generator = new Random();
to the SuburbanScene class.
Make the scene more random. Randomly generate the x and y positions of
the cars, houses, and balls, so that x < getWidth() and y
< getHeight().
Moveable Interfacepublic interface Moveable
{
void move();
}
Have the Car and Ball classes (but
not the House class) implement the
Moveable interface in addition to the Drawable
interface. Simply add a comma and Moveable to the class
declarations. Compile your code. What happens? Why?
move method for Car, simply execute
x = x + 5, and for Ball, y--.
Provide these methods and compile your code. It should now compile without errors.
d.draw(g2) (or whatever you called
the Drawable), add the lines
if (d instanceof Moveable)
{
d.move();
}
Compile. What happens? Why?
move on a variable that isn't
of type Moveable. Here, we need to use a cast.
Moveable m = (Moveable) d;
The cast is safe because we already checked that d instanceof
Moveable. Using the cast, make the moveable objects move before they
are drawn. Compile to make sure you don't get any errors. What is your
paintComponent method now?
Attach the code for all classes to your lab report.
CarViewer class, add a JButton to the
frame, like this:
JButton button = new JButton("Move");
frame.add(button, BorderLayout.NORTH);
The JButton class is in the javax.swing
package, and BorderLayout is in java.awt.
Compile and run your program. Where is the button?
JPanel and then adding the
JPanel to the North. Implement this enhancement if you have
time.CarViewer class,
inside CarViewer.java.
class MoveListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("move");
}
}
Compile and run the program. What happens when you click the button?
MoveListener. In the main method, construct an
object listener of your MoveListener. Then call
button.addActionListener(listener);
Compile and run the program. What happens when you click the button?
repaint method, which calls
paintComponent on all components in the frame, which then
calls move and draw. So, we want to call
frame.repaint();
in the actionPerformed method of the
MoveListener. Replace System.out.printl("move")
with frame.repaint(). Compile. What happens? Why?
frame variable isn't in the scope of the
actionPerformed method. To fix this, move the entire
MoveListener class inside the main method,
just before the declaration of the listener variable. Compile.
What happens?final to the declaration of the
frame variable.
final JFrame frame = new JFrame();
Now compile and run your program. What happens when you click the button a few times?
Attach the code for all classes to your lab report.
javax.swing.Timer.
Add a Timer like this:
Timer t = new Timer(100, listener); // 100 milliseconds between actions t.start();
Run your program. What happens?
(To make the car movement prettier, change x = x + 5 to
x++.)
t.start().Measurable InterfaceMeasurable interface from the textbook is a bit
abstract. The following tasks should help with visualizing it.
Make the House class implement the Measurable interface. The
getMeasure method should return the area of the house
(width * height).
Compile the class to make sure there are no syntax errors. Attach the code to your lab report.
CarComponent, add an instance variable
private Measurable largest;
In the constructor, add a local variable data of type DataSet. Add all houses to the data
set, then set largest to data.getMaximum().
In the paintComponent class, locate the call to
d.draw(g2) (or whatever variable you used) and change it to
if (d == largest) g2.setColor(Color.GREEN); d.draw(g2); g2.setColor(Color.BLACK);
Now run your program. What happens? Why?