When designing a basic application program, certain details may be elusive. For example, how many variables will be needed, or how many methods will need to be created. There is no simple prescription that can handle all of the possibilities. The only thing that can be done is begin to process the information and formulate a plan of attack.
When planning the strategy, other details will surface and stare glaringly back. More may simply be present waiting to be discovered. The next example details when the project needs more in order to be complete. In the program, the following will be addressed:
- The set of variables.
- The approach to gathering information.
- Dealing with bad input.
- Providing a method of escape.
- Project morphing.
In Perimeter1, the program is simply calculating the perimeter of a quadrilateral using the length and width represented by l and w, respectively. The approach is simple, direct and uses a GUI to gather data and report results. The program is wrought with issues, however.
- The programmer has chosen showInputDialog()for user input. This always returns a String.
- The calculation can only be done with doubles, so each Stringwill need to be converted usingparseDouble()from theDoublewrapper class.
- The parseDouble()method will throw aNumberFormatExceptionon values that are not in floating point format.
- There are two places where an exception can occur. Lines 10 and 13 where parseDouble()is invoked.
import javax.swing.JOptionPane;
public class Perimeter1 {
    public static void main(String[] args) {
        double l, w, p;
        String i, output;
        
        i = JOptionPane.showInputDialog("Enter the length");
        l = Double.parseDouble(i);
        
        i = JOptionPane.showInputDialog("Enter the width");
        w = Double.parseDouble(i);
        
        p = 2 * w + 2 * l;
        
        output = String.format("The length is %.2f%n", l)
                + String.format("The width is %.2f%n", w)
                + String.format("The perimiter is %.2f", p);
        
        JOptionPane.showMessageDialog(null, output);
        
        System.exit(0);
    }
}
The Perimeter2 program attempts to address the issue of exceptions.  This introduces new problems that must be handled.
- Wrapping the parseDouble()calls with atryblock isolated the scope of assignment. This causes the compiler to believe that bothlandwmay not have been initialized due to their assignment within the scope of thetryblock. The variableslandwneed to be initialized on line 6.
- The catchblocks usesshowMessageDialog()to display a message of failure, but the programmer is now relegated to terminating the program since continuing on is not an option.
import javax.swing.JOptionPane;
public class Perimeter2 {
    public static void main(String[] args) {
        double l = 0.0, w = 0.0, p;
        String i, output;
        
        try {
            i = JOptionPane.showInputDialog("Enter the length");
            l = Double.parseDouble(i);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Naughty!");
            System.exit(1);
        }
        
        try {
            i = JOptionPane.showInputDialog("Enter the width");
            w = Double.parseDouble(i);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Naughty!");
            System.exit(1);
        }
        
        p = 2 * w + 2 * l;
        
        output = String.format("The length is %.2f%n", l)
                + String.format("The width is %.2f%n", w)
                + String.format("The perimiter is %.2f", p);
        
        JOptionPane.showMessageDialog(null, output);
        
        System.exit(0);
    }
}
Perimeter3 attempts to address the problems presented in Perimeter2 and does a relatively good job in doing so. Of course, new issues are introduced that must be handled.
- Wrapping the try/catchblocks inwhileloops can help to promote a self-adjusting, self-healing solution. It also requires the addition of abooleanto know when the input has been successful.
- The okvariable needs to be reset prior to starting the second loop for the width as this would now be true from the previous loop causing the program to bypass the second loop altogether.
- Those paying close attention to this process are now considering the fact that code has repeated since we wrote Perimeter1and has now escalated to the point where a method is a better fit to eliminate the repetition of code and reduction in the number of variables.
import javax.swing.JOptionPane;
public class Perimeter3 {
    public static void main(String[] args) {
        double l = 0.0, w = 0.0, p;
        String i, output;
        boolean ok = false;
        
        while (!ok)
            try {
                i = JOptionPane.showInputDialog("Enter the length");
                l = Double.parseDouble(i);
                ok = true;
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, "Naughty! Try again.");
            }
        
        ok = false;
        while (!ok)
            try {
                i = JOptionPane.showInputDialog("Enter the width");
                w = Double.parseDouble(i);
                ok = true;
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, "Naughty! Try again");
            }
        
        p = 2 * w + 2 * l;
        
        output = String.format("The length is %.2f%n", l)
                + String.format("The width is %.2f%n", w)
                + String.format("The perimiter is %.2f", p);
        
        JOptionPane.showMessageDialog(null, output);
        
        System.exit(0);
    }
}
Perimeter4 is a complete solution that addresses all issues discovered throughout the process.
- The getValue()method eliminates the need for a boolean and simply loops forever.
- The parseDouble()call is the object of thereturnstatement eliminating additional variables.
- The user prompt is passed as an argument to getValue().
- The main()method is smaller, simpler and no longer requires the initialization oflandw.
import javax.swing.JOptionPane;
public class Perimeter4 {
    public static double getValue(String p) {
        String i;
        
        while (true)
            try {
                i = JOptionPane.showInputDialog(p);
                return Double.parseDouble(i);
            } catch (Exception e) {
                JOptionPane.showMessageDialog(null, "Naughty! Try again.");
            }
    }
    
    public static void main(String[] args) {
        String output;
        double l, w, p;
        l = getValue("Enter the length");
        w = getValue("Enter the width");
        
        p = 2 * w + 2 * l;
        
        output = String.format("The length is %.2f%n", l)
                + String.format("The width is %.2f%n", w)
                + String.format("The perimiter is %.2f", p);
        
        JOptionPane.showMessageDialog(null, output);
        
        System.exit(0);
    }
}