P1. Implementing an Interface

The Comparable interface is a commonly used interface in Java. Look up the Comparable interface in the API documentation.

If you wanted to modify the Coin class so that it realizes the Comparable interface, what method(s) do you need to implement?

Give the method signatures, that is, the return type(s), the method name(s), and the method parameter(s).



The compareTo method compares two parameters, the implicit and explicit parameter. The call



   1 if a is larger than b
   -1 if a is smaller than b
   0 if a and b are the same

Implement the compareTo method of the Coin class so that it compares the numerical values of the coins.



The sort method of the Collections class can sort a list of objects of classes that implement the Comparable interface.

Here is the outline of the required code.

import java.util.ArrayList;
import java.util.Collections;
. . .

// put coins into a list
ArrayList list = new ArrayList();

// call the library sort method

// print out the sorted list
for (int i = 0; i < list.size(); i++)
  Coin c = (Coin)list.get(i);
  System.out.println(c.getName() + " " + c.getValue());

Using this outline, write a test program that sorts a list of five coins: one penny, two nickels, one dime, and one quarter.

Enter your test program here.



What is the outcome of executing your test program? Remember that you must use the version of the Coin class that implements the Comparable interface.



Change your compareTo method by switching the return values 1 and -1. Recompile and run the test program again. What is the outcome of executing your test program? Explain the changed output.



P2. A Strategy Interface

Modify the test program so that it sorts Rectangle objects:

Rectangle rect1 = new Rectangle(5, 10, 20, 30);
Rectangle rect2 = new Rectangle(10, 20, 30, 15);
Rectangle rect3 = new Rectangle(20, 30, 45, 10);


// call the library sort method

// print out the sorted list
for (int i = 0; i < list.size(); i++)
  Rectangle r = (Rectangle)list.get(i);
  System.out.println(r.getWidth() + " " + c.getHeight());

When you run the program, you will get an error message. What is the error message? What is the reason for the error message?



Unfortunately, you cannot modify the Rectangle class so that it implements the Comparable interface. The Rectangle class is part of the standard library, and you cannot modify library classes.

Fortunately, there is a second sort method that you can use to sort a list of objects of any class, even if the class doesn't implement the Comparable interface.

Comparator comp = . . .;
Collections.sort(list, comp);

Comparator is an interface. Therefore, comp must be constructed as an object of some class that implements the Comparator interface.

What method(s) must that class implement? (Hint: Look up the Comparator interface in the API documentation.)



Implement a class RectangleComparator whose compare method compares two rectangles.

   1 if the area of the first rectangle is larger than the area of the second rectangle   
   -1 if the area of the first rectangle is smaller than the area of the second rectangle
   0 if the two rectangles have the same area

Remember that you need to cast the two Object parameters to the Rectangle type.

What is the code for your RectangleComparator class?



Write a test program that adds the three rectangles given previously to a list, constructs a rectangle comparator, sorts the list, and prints the sorted list.

What is your test program?



What is the output of your test program?



A very specialized class, such as the RectangleComparator, can be defined inside the method that uses it.

Reorganize your program so that the RectangleComparator class is defined inside the main method of your test class.

What is your main method now?



P3. Event Handling

A timer notifies a listener at regular time intervals. The time interval is given in milliseconds. The listener must implement the ActionListener interface.
For example, the call

Timer t = new Timer(1000, listener);

causes the timer to call the actionPerformed method once per second.

To see the timer at work, install a listener that simply prints out the current time. To print out the current time call

import java.util.Date;
. . .
System.out.println(new Date());

Supply a class CurrentTimePrinter that implements the ActionListener interface and whose actionPerformed method prints the current time.

What is the code for the CurrentTimePrinter class?



Now put together a test program that prints the current time once each second.

Construct a CurrentTimePrinter, construct and start a timer, and put up a message dialog so that the program user can quit the program.

JOptionPane.showMessageDialog(null, "Quit?");

Enter your test program here.



The program of the preceding exercise keeps printing the time, once per second. In this exercise, you will modify the program so that it stops the timer after 15 seconds, restarts it after another 15 seconds, stops it after a further 15 seconds, and so on.

Of course, we will use a second timer for this purpose. Here is the implementation:

class TimerToggler implements ActionListener
  public void actionPerformed(ActionEvent event)
     if (t.isRunning())

ActionListener listener2 = new TimerToggler();
Timer t2 = new Timer(15000, listener2);

Add the code that defines t2 after the instruction for starting t and before displaying the option pane. Compile the code.

What compiler error do you get? Why? What can you do to avoid it?



Fix your program so that the first timer is declared as final. Methods of inner classes can access only final local variables of the enclosing method.

Your program should now compile and run. Execute it for approximately one minute. What output do you get?



It is a nuisance that the user must stop the program by clicking a button. Solve that problem by automatically stopping the program after two minutes (or 12,000 milliseconds). Simply make a timer listener that calls System.exit(0) in the actionPerformed method of its action listener.

Write the code for the third timer.



Now add the code for your third timer to the program and remove the last two lines of main, that is, the message dialog display and the call to System.exit(0).

Compile your program and run it.

Does it work as expected? If not, why?



The program exited immediately when exiting main, so the timers never ran.

To keep main alive, you'll need to add the message dialog back in. Simply add the line

JOptionPane.showMessageDialog(null, "Please wait");

to the end of main.

Now the program will run for two minutes, then exit. What output do you get?



R1. Type Conversion

As you can tell from the API documentation, the String class implements the Comparable interface. Therefore, it is legal to assign a String object to a Comparable variable:

Comparable c = "Hello"; // Ok

Which of the following assignments are legal?

   1. Measurable m = "Hello";
   2. Comparable d = new Rectangle(5, 10, 15, 20);
   3. Shape s = new Rectangle(5, 10, 15, 20);
   4. String t = c;
   5. t = (String)c;
   6. t = (String)d;
   7. if (d instanceof String) t = (String)d;