Concepts / Modal and Modeless Dialogs

Modal and Modeless Dialogs

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

  • Programming

A Question Hidden Inside Every Dialog

A graphical program often needs to stop and ask the user something. It may need a color, a yes or no decision, a name, or it may simply need 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.

What do you think happens?

A program calls an input dialog asking for a name. The user clears the text box, leaves it empty, and presses OK. What does the method return?

  • null

  • An empty string

  • The number zero

  • Nothing, because the method has no return value

Reveal answer
Answer:

An empty string

Pressing OK with no characters typed returns an empty string, which is a real String object that has no characters. Null is reserved for the case where the user clicks Cancel or closes the window. Those two results look similar when printed but must be handled separately.

The idea behind every predefined dialog is simple. The details that matter are in the return values. Each 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. The rest of this article keeps the question of what comes back at the center of each dialog.

Four Dialogs and Their Providers

Two Swing classes supply the four dialogs covered here. JColorChooser provides a single dialog, the color chooser, 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. Variations can add a title, a special icon, or extra components, but the basic forms are enough to understand the pattern.

DialogProvided byWhat the call gives back
Color chooserJColorChooser (showDialog)A Color, or null if the user cancels or closes the dialog
Message dialogJOptionPaneNothing (void return type)
Input dialogJOptionPaneA String, which may be null, empty, or contain typed text
Confirm dialogJOptionPaneAn int constant naming the button or action that ended the dialog

The four predefined dialogs, their providing class, and their return values

Notice that the table is organized around return values, not around how the window looks. The same question, what came back, governs how each call should be handled. The message dialog is the one exception: nothing comes back at all, so there is nothing to check.

Pausing for the User

The color chooser's showDialog() method is modal. This means the method 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. The JOptionPane dialogs follow the same pattern: the program makes a call, the window appears, the user responds, and the result comes back to the calling code. Trace the order of events in the diagram below.

ProgramJColorChooserUsershowDialog() is calleddialog waits for a choiceselects a color and presses OKreturns the chosen Color
In what order do the statements run around a modal dialog call, and at what point does execution resume after the user dismisses it?

The diagram shows the key point. The program's next statement does not begin until the return arrow reaches the program. Any code written after the call can therefore safely assume the user has already made a decision. The program does not need to poll the dialog or check whether it is still open.

Reading Input Results Carefully

An input dialog shows a question, an input box, and OK and Cancel buttons. Its method returns a String, and that String can take three different shapes. 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. This is a real String object that happens to have no characters. If the user types something and clicks OK, the result is that text. Each shape needs its own handling.

Input dialog shownWhat did the user do?nullCancel or window closedEmpty stringOK with no textTyped textOK with text in the boxCancel or closeOK, box emptyOK, text typed
When the user presses Cancel, closes the window, presses OK with no text, or types text and presses OK, which path does the returned value take, and where does a null check or an empty-string check fit?

Read the flowchart as a set of branches. Only the null branch and the empty-string branch need separate checks, because the typed-text branch is the path the author usually has in mind. A null check catches the cancel case, and a check for an empty string catches the case where the user pressed OK without typing. Checking only one of them leaves the other path unhandled.

The dialog also returns text even when the program wants a number. Converting the returned string into a numeric value is a separate step, covered in the source's discussion of converting strings to numbers. The input dialog only ever gives back a String.

java
Output
If the user types Ada and presses OK, the program prints: Hello, Ada
Notes on the code
  • The call returns only after the user responds, so the next line sees the final result.
  • The null check comes first because calling a method on null would fail.
  • The isEmpty check handles OK with no text, which is a different case from Cancel.

Worked Trace of Three Input Outcomes

Worked example

Tracing the name program through three user actions

The program in the previous section asks for a name. Determine what each of three user actions prints.

  1. 1
    Case one: the user clicks Cancel

    The method returns null. The first condition, name equals null, is true, so the program prints the cancelled message. The isEmpty check is never reached.

  2. 2
    Case two: the user presses OK with the box empty

    The method returns an empty string. The null test is false, so the program moves to the isEmpty test, which is true, and it prints the message for OK with nothing typed.

  3. 3
    Case three: the user types Ada and presses OK

    The method returns the string Ada. Both earlier tests are false, so the final else branch runs and prints Hello, Ada.

Result

Three different outcomes come from three user actions. If the program had only the else branch, cases one and two would both crash or behave incorrectly, which is why each shape needs its own handling.

Confirm Dialog Constants and Their Meaning

A confirm dialog poses a question and offers Yes, No, and Cancel buttons. 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. Each constant names a particular way the dialog was ended, including closing the window without choosing a button. The mapping below shows what each constant could mean for the program's next step. The next steps are illustrative choices for one program, not behavior the dialog itself prescribes.

YES_OPTIONSave the fileNO_OPTIONDiscard the changesCANCEL_OPTIONReturn to the editorCLOSED_OPTIONWindow closed without abutton
Which constant or integer does each user action produce from a confirm dialog, and how does each map to the program's next step?

A yes-no form can omit the Cancel button. The source describes a different overload that accepts a constant selecting the button set. Passing the yes-no option constant leaves the user with only Yes and No, which is written JOptionPane.YES_NO_OPTION in Java. Because Cancel is absent, the program should not expect a cancel result from that form, but the closed-window case still needs thought.

java
Notes on the code
  • The result is stored in an int, not a String, so it is compared with constants.
  • The else branch here catches cancel and closing the window, which is a deliberate design choice the author must make.

Color Chooser Cancel Case

The color chooser is the most self-contained of the four dialogs. The method takes three parameters. The first identifies the parent component, which determines which window the dialog belongs to, and it may be null. The second is the string shown in the title bar. The third is the color already selected when the dialog first appears. 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 of a color.

java
Notes on the code
  • The null check must come before any use of picked, because a Cancel leaves no Color object to use.

Modal Versus Modeless Behavior

A modal dialog blocks the flow of the program. The call waits until the user responds, and only then does the next statement run. The source describes this behavior for the color chooser. The four dialogs in this article follow the same request-and-response pattern: the program makes one call and receives one result back. A modeless window, by contrast, is one the program can leave open while it keeps running. The call returns immediately rather than waiting for the user. The source does not describe modeless windows in detail, so treat the contrast as a way to think about the waiting behavior rather than as a full catalogue of options.

QuestionModal dialogModeless window
Does the call wait for the user?YesNo, the call returns right away
Is the next line safe to read the result from?Yes, the result is readyNot automatically, the user may not have responded yet
Example in this articleColor chooser showDialog(), and JOptionPane dialogsNot covered by the source

Modal and modeless behavior compared for the dialog calls in this article

Mistakes Beginners Make With Dialog Results

  • Common mistake

    Treating null and the empty string as the same thing

    What it looks like
    if (name.isEmpty()) used alone, when the user pressed Cancel
    Why it fails

    Cancel returns null, which has no object behind it, so calling isEmpty on it fails. The empty string is a valid String that has no characters.

    Do this instead

    Test for null first, then test for an empty string, as in the name program.

  • Common mistake

    Assuming the color chooser always returns a color

    What it looks like

    Using picked directly in a call that sets a background color, without checking it first

    Why it fails

    If the user cancels or closes the dialog, the method returns null instead of a Color.

    Do this instead

    Check for null after the call and keep the previous color in that case.

  • Common mistake

    Expecting a confirm dialog to return true or false

    What it looks like
    boolean ok = JOptionPane.showConfirmDialog(...)
    Why it fails

    The confirm dialog returns an int constant, not a boolean, and it can represent more than two outcomes.

    Do this instead

    Store the result in an int and compare it with JOptionPane constants such as YES_OPTION.

  • Common mistake

    Expecting an input dialog to return a number

    What it looks like
    int age = JOptionPane.showInputDialog(...)
    Why it fails

    The input dialog returns a String, so the value must be converted in a separate step.

    Do this instead

    Read the result as a String, check it for null and empty, then convert it.

  • Common mistake

    Expecting a long message to wrap automatically

    What it looks like

    A long sentence passed to showMessageDialog with no line breaks

    Why it fails

    The dialog will not insert line breaks by itself, so the text appears as one wide line.

    Do this instead

    Insert explicit newline characters, written as backslash-n, where the lines should break.

Finding Where the Program Diverges

When a dialog-based program misbehaves, the fault is usually at one point: the line where a returned value was used without the check it needed. The most useful habit is to ask, at each dialog call, what the possible return values are, and then to follow each one to the branch it reaches. The question is never whether the dialog appeared, but which value came back and whether the code handled it. Running the program and watching the variable that holds the result shows the moment the expected path and the actual path separate.

MEDIUM

A program calls the color chooser, stores the result in a variable named picked, and then calls picked.equals(Color.RED) to decide on a message. Trace what happens when the user presses Cancel. At which exact line does the program's behavior diverge from what the author expected, and what single check would prevent it?

Hints
  • List the two possible return values of showDialog() before you trace the code.
  • Ask what picked contains after Cancel, and what happens when a method is called on that value.
  • The fix is a check that comes between the dialog call and the first use of picked.

Key Takeaways

  • JColorChooser provides the color chooser through showDialog(), and JOptionPane provides the message, input, and confirm dialogs.
  • Each dialog returns something different: a Color or null, nothing at all, a String or null, or an int constant identifying how the dialog ended.
  • An input dialog returns null when the user cancels or closes the window, an empty string when OK is pressed with no text, and the typed text otherwise. Null and the empty string must be handled separately.
  • A confirm dialog returns one of four JOptionPane constants, including Yes, No, Cancel, and closing the window, and a yes-no form can omit the Cancel button.
  • Dialogs like the color chooser are modal, so the call does not return until the user responds. When a result looks wrong, trace each possible return value to the branch it reaches to locate the divergence.