CSCI 580E/470 - Assignment 3 - Fall 2009


How many times have you had a decimal fraction like .13 or .47 and needed to know the nearest regular fraction with a given denominator?  Or the best fraction with a denominator no greater than a given number.  If you're like me, probably it happens 2 or 3 times a day, right?  (Ok, just pretend...)

Write a Java applet called Frac1.java which will allow the user to enter a decimal fraction between 0 and 1 (such as .83 or .1415) and the denominator to be used by the program to find the fraction closest to the decimal fraction entered.  For example,

  1. if the user types in .34 as the number and 3 as the denominator to use, the program will find and display the fraction 1/3.
  2. if the user types in .82 as the number and 6 as the denominator to use, the program will find and display the fraction 5/6.
  3. if the user types in .83 as the number and 8 as the denominator to use, the program will find and display the fraction 7/8.

The program will also display the error (i.e. the difference between the fraction and the originally entered number).  For example, in

  1. example 1 it will display:  1/3  (result is .0067 less than the value entered)
  2. example 2 it will display 5/6  (result is .0133 more than the value entered)
  3. example 3 it will display  7/8  (result is .045 more than the value entered)

You should do this via a brute-force approach: simply try each fraction for the given denominator, and remember the one closest to the entered number.  That is, for example 2, try 0/6, 1/6, 2/6, 3/6, 4/6, and 5/6  If the fraction is exact (e.g. .5 = 1/2) then display "the fraction is exact".

The number entered should be greater than 0.0 and less than 1.0.  The fraction denominator should be less than 100 (just to keep the loop fast).  See below.

You will write two versions of a GUI applet using the Swing GUI library .  You can develop these locally on your Windows computer and test them via appletviewer locally.  Once each is complete and debugged, it should be deployed to the Web as an applet embedded in a Web page.  Suggestions:

Version 1

For this part you will use a simple but ugly GridLayout, similar to the following (click on the image for a full-size version):

The following notes supply some useful details and specifications.

1. Use final data members to define the various maximum and minimums.  Use 0.001 to 0.999 as the decimal value limits, and use 2 to 100 as the denominator limits.  These constants should appear nowhere else in the program, including the JLabel construtors' text.  This way, if the limits change in the future they need only be altered in one place in the code.

2. Error checking should be done when the Calculate JButton is pressed.  If any error occurs, set an informative message in the Info/Message JTextArea and do not process the request.  Check for the following conditions:

You need only report one error, even if multiple errors occur.

3. You will provide two calculation options: "use specified denominator" and "use best denominator". To find out which calculation option the user has chosen, use JCheckbox's isSelected() method.

3. Write a method called calcBestFrac().  This method will take the decimal fraction and a denominator value as arguments.  It should calculate and return the numerator of the fraction it finds as well as the error amount.  But a method cannot return two values.  Neither can it pass simple (primitive) arguments by address or reference.  So you will need to create a simple helper class (see Results class, below) to hold the calculated results.  When you call calcBestFrac(), pass it an instance of this class as a third argument.  The method will fill in the values it finds, and then, upon return, the calling program can access them.

4. The Results class

This class should hold three values:

You should also write and use public access methods to get and set these values.  Note that only one class in a source code module can be declared public.  So this class should simply be declared as

class Results {...}

5. If your final result can be reduced, it should be.  For example, if you enter .5 and ask for 8ths, the result should display as 4/8 (with a message that the answer is exact) and then it should also be displayed in reduced form: 1/2.  To help with this in the "use specified denominator" case, write and use a small helper function to find the greatest common factor (GCF) of (any) two integers.

6. For "use best denominator", test all denominators from 2 up to and including the user-entered value.  For example, if the user enters 5, then try

0/2, 1/2
0/3,1/3, 2/3
0/4,1/4, 2/4, 3/4
0/5,1/5, 2/5, 3/5, 4/5

and report the best (closest) fraction. 

Note that this procedure will find the fraction in lowest terms first (if you write your loops going from lowest to highest denominator values) so the GCF calculation is unnecessary.

In the example above, you should report 1/2 rather than 2/4 if that is the closest fit.

4. You can use TextComponent's setText() to replace text in a JTextArea and append() to add more text to a JTextArea.  The notation "\n" will create a newline.

5. Use the JLabel constructor version that allows you to set text justification to RIGHT to get the appearance you see above.

6. The Reset button should clear the text from all JTextFields and JTextAreas.  Text should be set to no characters, not one or more blank characters.

Version 2

This version will use a somewhat more attractive Layout, via tabbed JPanels.  You may devise your own layout as long as it is organized and logical or you may use the model below if you like.  Probably you can devise more attractive colors, but make sure that all labels and text are easy to read.  It was created via JPanels, BorderLayout, and GridLayout (click on the images for full-size versions).  In addition, you will implement new functionality (the right-hand image shown below).  Details are given below.

     

1. This program will clearly have additional controls and components.  The question arises: where should you declare them?  As applet data members or as members of custom Panel classes?  For this assignment, declare them all as applet data members.  You will then create and add them in the applet's init().  Notice that there are now two Calculate JButtons, and two of several other controls.  You will need a naming scheme to distinguish them.  Your JPanels, then, can be just JPanels - you do not have to create a special derived version.

2. Use Component's setBackground() to give a distinct color to the applet and each tabbed Panel.  Use as the argument new Color(r, g, b) where r, g, and b are integers in the range of 0 to 255.  Make sure that text is visible against the background.

3. If you didn't before, use the Layout constructors that place some room between components so they do not appear pushed together.

The Fractions Calculator

The Calculate Tab part of the applet (the right-hand image above) is used to do fraction arithmetic.  The user will type in two fractions (like 1/3 and 4/7) and choose an operation (add, subtract, multiply, or divide) and then will click the Calculate JButton (in this section).  The result will appear in the Result JTextArea as a fraction.  If it can be reduced, the reduced form will be shown on a second line in that JTextArea. 

Error checking should be done here, as well.  Check for the following:

Once the user input is valid and the numerator and denominator strings are converted to integers, do the appropriate arithmetic and display the answer, as a fraction.  If it can be reduced, reduce it and display that value as well.