Java, Java, Java!
Chapter 5: Java Data and Operators
In the Laboratory: The Leap Year Problem

R. Morelli

©2006 Prentice-Hall


In the Laboratory: The Leap Year Problem

The purpose of this lab is to emphasize the object-oriented design principles discussed in this and previous chapters and to use some of Java's basic language structures, such as if-else, assignment, and arithmetic expressions.

Problem Description

A year is a leap year if it is evenly divisible by 4 but not evenly divisible by 100 unless it is also evenly divisible by 400. So 1996 was a leap year. But 1900 was not a leap year because, although it is divisible by 4, it is also divisible by 100 and not by 400. 2000 is a leap year because it is divisible by 400.

Design and write a Java applet that allows the user to enter a year (as an integer) and reports whether the year entered is a leap year or not.

Problem Decomposition

One way to decompose this problem is to divide it into two classes, the LeapYearApplet class, which implements the user interface, and the Year class, which contains the expertise needed to decide whether a given value is a leap year or not. LeapYearApplet should get the input from the user (in a TextField), pass it to Year, converting it to whatever form Year requires, and then display the result that Year returns.

Problem Design: Year

The Year class is very simple. Its whole purpose in life is just to wait until it is passed a value and then to determine if that value is a leap year or not. One design we could use here is that of the Temperature class. In that case the temperature was stored as an instance variable, and public methods were used to set and get the temperature as either a Fahrenheit or Celsius value.

Another design that would be appropriate here is to model Year after the Math class -- that is, as a utility class that provides a useful method, but which is not designed to be instantiated at all. Since this latter design is simpler, let's adopt it.

The isLeapYear() method should be a public method that takes a single int parameter and returns the boolean value true if its parameter is a leap year and false otherwise. In terms of its algorithm, this method should use an if-else control structure to test whether a year is divisible by 400, by 100, and so on. To determine if an integer is divisible by another integer, you can use the mod operator (%). For example, if N % 100 equals 0, then N is divisible by 100. That is, N is divisible by 100 if dividing it by 100 leaves a remainder of 0:

    if (N % 100 == 0) ...

You may find it helpful to draw a flowchart for the isLeapYear(). See Chapter 3 to review the guidelines for drawing flowcharts.

Problem Design: LeapYearApplet

The design of the LeapYearApplet should be similar to that of other applets we've built. It should contain a TextField for user input and a Label for prompting the user. Its interface is shown in Figure 1. Note that the interface does not contain a Button. With no button to click, how does the user tell the applet to test whether a year is a leap year or not? The answer is that a TextField generates an action event whenever the user types the Enter key in it. As with button clicks, these events can be handled by an ActionListener. Therefore, after instantiating a TextField, you can simply register it with an appropriate ActionListener:

    inputField = new TextField(10);     // Create a TextField
    inputField.addActionListener(this); // Register it with a Listener

In this case, the applet's actionPerformed() method would handle the TextField's action events just as if it were a Button.


  
Figure 1: The LeapYearApplet.
\begin{figure}
\rule{4.75in}{.05cm}

\epsfig {file=/home/ram/java/text/ch5-models/figures/leapyear.eps}
\rule{4.75in}{.05cm}\end{figure}

The LeapYearApplet should implement the ActionListener.actionPerformed() method to handle TextField actions. When the user types Enter, actionPerformed() should get the input from the TextField and convert it from String to int. Recall that the parseInt() method in the Integer class can be used for this purpose:

    yearNum = Integer.parseInt(inputField.getText());

Here it is assumed that the user's input is in a text field instance variable named inputField and the integer is stored in an int instance variable named yearNum . The integer should then be passed to Year.isLeapYear(), which will return a boolean and the applet should then report the result.

How should this applet handle the reporting of the result? Perhaps the easiest way is to override Applet's paint() method, which was the approach we took in the HelloWorld applet in Chapter 1. Recall that paint() uses the following kind of statement to display a String on an applet:

    g.drawString("HelloWorld", 10, 50);

The g in this expression is a reference to paint()'s Graphics object, which controls any drawing or painting on the applet. The two numbers in the expression are the horizontal and vertical coordinates that specify where ``HelloWorld'' will be painted on the applet. You will have do some planning and experimenting to determine what values to use for these coordinates.

One important question remains: How will paint() know whether to report that the year is or is not a leap year? Perhaps the best way to handle this is to invoke the Year.isLeapYear() method. Suppose this boolean variable is named yearIsLeapYear. Recall, that since we have patterned Year after the Math class (and Integer class), there is no need to instantiate it in order to use its static methods. So the paint() method can check its value and print the appropriate message:

    if (Year.isLeapYear(yearNum)) 
        g.drawString(yearNum + " is a leap year", 10, 80);

As members of LeapYearApplet, both actionPerformed() and paint() will have access to yearNum.

Implementation

The implementation of this program is left to you as a lab (or programming) exercise. To run LeapYearApplet.class you will need to create a LeapYearApplet.html file that refers to the applet class in an applet tag.


Ralph Morelli {Faculty}
12/22/1999