Concepts / Dialogs in Java

Dialogs in Java

The predefined dialogs come from JColorChooser, which provides the color chooser, and from JOptionPane, which provides message, input, and confirm dialogs.

  • Programming

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?

  • An empty string

  • null

  • The text typed so far

  • Nothing; the program crashes

Reveal answer
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.

Color chooserColor or nullMessage dialognothing (void)Input dialogString or nullConfirm dialogint constant
Which class supplies each dialog, and what kind of value the call hands back to the program?
DialogProvided byWhat the method returns
Color chooserJColorChooser.showDialog()The chosen Color, or null if cancelled or closed
Message dialogJOptionPaneNothing; the method has a void return type
Input dialogJOptionPaneA String, or null if cancelled or closed
Confirm dialogJOptionPaneAn 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.

java
Notes on the code
  • 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.

showInputDialog()Question shown to userWhat did the user do?Typed text, pressedOKreturns the typed textUse the textPressed OK, box emptyreturns empty stringHandle as no inputPressed Cancel or Xreturns nullHandle as cancelledreturnstext enteredOK, nothing typedCancel or closeString of textempty Stringnull
After the user presses OK, Cancel, or the X button, which value does the input dialog return, and where does the code go next?

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.

java
Notes on the code
  • 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

Worked example

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?

  1. 1
    Run 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.

  2. 2
    Run 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.

  3. 3
    Run three

    Cancel was pressed. The method returns null. name == null is true, so the first branch runs and the isEmpty() call is never reached.

Result

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.

ProgramJOptionPaneUsershowInputDialog()shows questionpresses Cancelreturns nullname.toUpperCase() on null
At which call does the program's behavior split from what the author intended, when the user cancels an input dialog?
  • Common mistake

    Calling a method on the result before checking for null

    What it looks like
    String name = JOptionPane.showInputDialog(null, "Name?");
    System.out.println(name.toUpperCase());
    Why it fails

    If 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 instead

    Test name == null first, and only then call methods on it.

  • Common mistake

    Treating an empty string as if the user cancelled

    What it looks like
    if (name == null || name.isEmpty()) { return; }
    Why it fails

    This 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 instead

    Write 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 fails

    A 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 like
    Color c = JColorChooser.showDialog(null, "Pick", Color.RED);
    int r = c.getRed();
    Why it fails

    Cancelling or closing returns null, not the preselected color. Calling getRed() on null fails.

    Do this instead

    Check for null before using the Color, as in the PickBackground example.

Best practice

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 didConstant returnedTypical branch
Pressed YesJOptionPane.YES_OPTIONProceed with the action
Pressed NoJOptionPane.NO_OPTIONSkip the action
Pressed CancelJOptionPane.CANCEL_OPTIONStop and do nothing
Closed the windowJOptionPane.CLOSED_OPTIONTreat 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.

java
Notes on the code
  • 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

MEDIUM

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

  • JColorChooser provides the color chooser through showDialog(), and JOptionPane provides 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 JOptionPane constants, 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.