Hands on Testing Java: Lab #G01

GUI Lab #1

Introduction

Our problem today is to convert a text based program to use a graphical user interface. We won't do a full design, but concentrate on converting an existing program to use a graphical user interface wikipedia (GUI).

GUI versus CLI

Other than the JUnit test-case classes, you've written mostly command-line interface wikipedia (CLI) programs so far. These programs are typically called from the command line (i.e., in a terminal window), hence the name. In an IDE, you run these programs in a "console". A CLI interface is based almost solely on textual interaction with a screen and keyboard.

Most modern programs use GUIs to display the same information, just in more pleasing or more useful ways. However, it often requires more work for a programmer to write a GUI program. This GUI lab exercise explores one very simple (but not the best) way to write a GUI program.

The Code

Do this...

JUnit Test Code

Do this...
Run the test-case class to make sure that the test do, in fact, run for a green bar.

The CLI Code

The provided code implements a CLI for computing the area of a slice of pie.

Do this...
Run the PieSliceCLIDriver driver.

Take a look at the code for PieSliceCLIDriver. It's a pretty simple program. This program makes a sharp distinction between the data model and the user interface for the program. One class does all of the computation; a completely separate class provides the user interface. This is very common when writing any program, and this lab exercise will show why it's so important.

Turning the CLI into a GUI

Do this...
Create a new driver class called PieSliceGUIDriver.

The basic structure

The basic algorithm in PieSliceCLI#main() should work just fine in PieSliceGUIDriver#main().

Do this...
So copy main() over.

The compiler will now tell you what the problem in: the screen-and-keyboard methods of the CLI driver are not defined in the GUI driver.

Do this...
Write method stubs for these other two methods.

Do not copy these methods over because they do not provide the behavior that you want.

An annoying difference

GUI programs not only require more work from programmers, but the runtime system has to do more work. For some reasons we'll gloss over now, you have to tell your GUI when to stop executing. CLIs will automatically stop when execution reaches the end of the main() method; GUIs will not.

Do this...
So add this code to the end of PieSliceGUIDriver#main():

System.exit(0);

The program will exit as soon as it reaches this statement; the 0 just indicates that the program quit naturally.

From CLI to GUI

Helpful hint: The package is javax.swing, not java.swing.

Instead of using the Screen and Keyboard classes, you'll use widgets from Java's Swing library wikipedia. This library can be found in the javax.swing packages and its sub-packages in any standard implementation of Java.

For this interlude, you will use the JOptionPane class. It allows you to prompt the user for some input and so display results. To be honest, GUIs are not based primarily on the JOptionPane class, but it's a fairly good way to get started with a GUI. This class is usually used to solve tiny little problems in larger GUIs.

The JOptionPane class has several class methods:

Look again at the code for the CLI. The one method prompts the user for two input values, and the other method tells the user the area of the pie slice. Looking over the methods listed above, it appears that showInputDialog() can take the place of our keyboard input and that showMessageDialog() can take the place of screen printing.

The method is invoked like so:

JOptionPane.showInputDialog(parent, message, title, messageType)

Consider an example: if I wanted to ask my user for her age, I could write this code:

String ageString = JOptionPane.showInputDialog( null,
                                         "What is your age?",
                                         "User Age Query Dialog",
                                         JOptionPane.QUESTION_MESSAGE);

Unfortunately, the result returned by this method is not a number, but a String.

Fortunately, I can use Double#parseDouble(String) to extract the double value from a String, like so:

double age = Double.parseDouble(ageString);

Do this...
Using my example, write code in PieSliceGUIDriver#readPieSlice() to prompt for and read in a radius and an angle. Then it should return a new PieSlice object. (Hint: you'll need two calls to JOptionPane#showInputDialog().)

You'll need to import the JOptionPane class from javax.swing.

Do this...
When you have PieSliceGUIDriver#readPieSlice() written; write the code for PieSliceGUIDriver#printArea(PieSlice).

This will need a call to JOptionPane#showMessageDialog() which receives the same parameters as JOptionPane#showInputDialog().

Think About It

By separating the computation class from the user-interface class, we can easily write as many user-interfaces as we want for this computation. It also allows us to forget and ignore what's actually happening in the computation; it's mostly irrelevant when we build a user-interface.

This is one of the important powers of object-oriented programming.

Submit

Terminology

CLI, command-line interface, data model, graphical user interface, GUI, Swing library, user interface, widgets