Dialogs in Java
The predefined dialogs come from JColorChooser, which provides the color chooser, and from JOptionPane, which provides message, input, and confirm dialogs.
When the Program Waits for an Answer
A graphical program often has to stop and ask the user something: which color to use, whether to go ahead, what the user's name is, or simply to deliver a warning. Building a dialog box from scratch for each of these jobs would take many lines of layout code. Java Swing avoids that work by providing dialogs that already exist as ready-made windows. Your program calls one method, the window appears, the user responds, and the method hands a result back to your code.
The idea is simple, but the details that matter are in the return values. Each predefined dialog gives back something different, and a program that ignores those differences will misbehave when the user does something other than click the most obvious button. Keep one question at the center of everything that follows: what comes back?
What do you think happens?
If the user clicks Cancel on an input dialog, what does the String variable that receives the result hold?
Reveal answer
null
Cancelling an input dialog returns null. Clicking OK with an empty box is different: it returns an empty string. The two cases must be handled separately.
The Four Predefined Dialogs and Their Classes
Two Swing classes supply the dialogs covered here. JColorChooser provides a single color selection dialog through its showDialog() method. JOptionPane is a more general class that offers a family of simple dialogs. Its variations fall into three basic types: a message dialog, a confirm dialog, and an input dialog. The variations allow a title, a special icon, or extra components, but the basic forms are enough to understand the pattern.
So the four dialogs are the color chooser, the message dialog, the input dialog, and the confirm dialog. The first comes from JColorChooser; the other three come from JOptionPane. Each one sends a different kind of result back to the program, which is why the class you call tells you a good deal about what to expect.
| Dialog | Provided by | What the method returns |
|---|---|---|
| Color chooser | JColorChooser.showDialog() | The chosen Color, or null if cancelled or closed |
| Message dialog | JOptionPane | Nothing; the method has a void return type |
| Input dialog | JOptionPane | A String, or null if cancelled or closed |
| Confirm dialog | JOptionPane | An int, one of four JOptionPane constants |
Return values of the four predefined dialogs
Message and Color Dialogs
The message dialog is the simplest of the three JOptionPane forms. It displays a string, and the user reads it and clicks OK. Nothing comes back to the program, so the method has a void return type. The first parameter identifies the parent component, and the second is the message text. Because nothing is returned, there is no value to check afterward; the only thing a message dialog can affect is what the user sees.
The color chooser is the most self-contained of the four. A single call opens a dialog with a sophisticated interface, and the user selects a color inside it. The method takes three parameters. The first identifies the parent component, which determines which window the dialog belongs to, and this parameter may be null. The second is a string shown in the title bar. The third is the color that is already selected when the dialog first appears.
Two details about the return value matter in practice. If the user presses OK, the chosen color is returned. If the user presses Cancel, or closes the dialog some other way, the method returns null instead. The method is also modal: showDialog() does not return until the user has dismissed the dialog. Your code pauses at that line, and the next line runs only after the dialog is gone.
showDialog()pauses the program until the user dismisses the color dialog- The third argument, Color.BLUE, is the color selected when the dialog first opens
- A null result means Cancel was pressed or the window was closed
Input Dialogs and Their Three Return Shapes
An input dialog shows a question and an input box, along with OK and Cancel buttons. Its method returns a String, and that return value has three possible shapes, each needing its own handling. If the user clicks Cancel or closes the window, the result is null. If the user clicks OK with nothing typed, the result is an empty string, which is a real String object that happens to have no characters. If the user types something and clicks OK, the result is that text.
Notice that the empty-string path and the null path lead to different places in the program, even though both mean the user gave no usable text. A program that checks only for empty text will miss the null case, and a program that checks only for null will treat an empty box as a valid name. This is why the two cases must be handled separately.
- The null check comes first, because calling
isEmpty()on null would fail isEmpty()is true only for the empty string, not for null- Every branch must handle a result that is always a String or null
Tracing a Cancelled Name Entry
Three presses, three return values
A program calls showInputDialog() once for each of three separate runs: the user types Ada and presses OK; the user leaves the box empty and presses OK; the user presses Cancel. What does the String variable hold after each run, and which branch runs?
- 1Run one
The user typed Ada and pressed OK. The method returns the String Ada. The name == null test is false and
name.isEmpty()is false, so the else branch prints Hello, Ada. - 2Run two
The box was empty and OK was pressed. The method returns a real String with zero characters. name == null is false, but
name.isEmpty()is true, so the middle branch runs. - 3Run three
Cancel was pressed. The method returns null. name == null is true, so the first branch runs and the
isEmpty()call is never reached.
Three different outcomes come from one method call: text, an empty string, and null. The null test must come before any method call on the variable.
Where the Program Diverges
When a dialog-driven program misbehaves, the fault is usually at a single point: the line where a returned value was used without the check it needed. The sequence below follows one call from the program to the dialog and back. The point where the author's expectation and the actual behavior split is the step where the program calls a method on a null return value.
Common mistake Calling a method on the result before checking for null
What it looks likeString name = JOptionPane.showInputDialog(null, "Name?"); System.out.println(name.toUpperCase());Why it failsIf the user cancels, name holds null, and calling
toUpperCase()on null fails at that line. The author's expectation was that a name always arrives, but the dialog can return null.Do this insteadTest name == null first, and only then call methods on it.
Common mistake Treating an empty string as if the user cancelled
What it looks likeif (name == null || name.isEmpty()) { return; }Why it failsThis happens to work, but it hides the difference between cancelling and pressing OK with nothing typed. The source says these two cases must be handled separately.
Do this insteadWrite a separate branch for null and another for the empty string, so each path can respond differently.
Common mistake Assuming a message dialog gives the program information back
Why it failsA message dialog returns nothing, because its method has a void return type. Code that waits for a value from it has nothing to receive.
Common mistake Expecting the color chooser to return a default color when cancelled
What it looks likeColor c = JColorChooser.showDialog(null, "Pick", Color.RED); int r = c.getRed();Why it failsCancelling or closing returns null, not the preselected color. Calling
getRed()on null fails.Do this insteadCheck for null before using the Color, as in the PickBackground example.
At each dialog call, ask two questions: what are the possible return values, and which branch does each one reach? The question is never whether the dialog appeared. Running the program and watching the variable that holds the result shows the moment the expected path and the actual path separate.
Confirm Dialogs and Their Four Constants
A confirm dialog poses a question and offers three buttons: Yes, No, and Cancel. Unlike the other dialogs, its method returns an int rather than a string or object. That integer is one of four constants defined on JOptionPane, and each constant names a particular way the dialog was ended: Yes, No, Cancel, or closing the window. The program does not compare the result to a string; it compares the int to these constants.
| What the user did | Constant returned | Typical branch |
|---|---|---|
| Pressed Yes | JOptionPane.YES_OPTION | Proceed with the action |
| Pressed No | JOptionPane.NO_OPTION | Skip the action |
| Pressed Cancel | JOptionPane.CANCEL_OPTION | Stop and do nothing |
| Closed the window | JOptionPane.CLOSED_OPTION | Treat as cancelled |
Each user action maps to one JOptionPane constant
A confirm dialog can be made without the Cancel button. A different overload accepts a fifth argument, a constant that selects the button set. Passing JOptionPane.YES_NO_OPTION leaves the user with only Yes and No. The title argument in that overload is the text shown in the dialog window's title bar. Even in this yes-no form, closing the window still produces one of the four constants, so a yes-no check must not assume that every result is either Yes or No.
- The fifth argument,
JOptionPane.YES_NO_OPTION, removes the Cancel button - The final else catches closing the window, which is not a Yes or No answer
- The result is compared to constants with ==, not to strings
Practicing the Return-Value Trace
A program asks Enter a number with an input dialog, and then calls the number parser on the returned text. The user presses Cancel. Trace what the String variable holds, state which check would prevent the failure, and say at which line the behavior first diverges from what the author expected.
Hints
- Start by writing down the three possible results of an input dialog: text, empty string, and null
- Ask which line first uses the variable as if it held a value
- Remember that the dialog gives back only a String, so converting it to a number is a separate step that also needs a valid value
Summary of Dialog Return Values
Each predefined dialog returns something different, and the difference is what the program must handle. The article's central habit is to list the possible return values at each dialog call and follow each one to its branch.
At a glance
JColorChooserprovides the color chooser throughshowDialog(), andJOptionPaneprovides the message, input, and confirm dialogs.- A color chooser returns a Color on OK and null on Cancel or close; a message dialog returns nothing; an input dialog returns a String; a confirm dialog returns an int constant.
- Cancelling or closing an input dialog returns null, while pressing OK with an empty box returns an empty string; these must be handled in separate branches.
- Confirm dialogs return one of four
JOptionPaneconstants, and even a yes-no form can be closed without choosing Yes or No. - Failures usually occur where a returned value is used without a check, so trace each dialog's possible results to the branch each one reaches.