CPSC 225, Spring 2011, April 18:
Dialog Boxes

This tutorial contains some examples of using dialog boxes -- both the standard ones and custom ones that you make yourself.

You will need the file Dialogs.java, which you will find in /classes/s11/cs225/tutorials. You will want to add this to an Eclipse project. You might just want to use the same project that you used for the mouse tools tutorial last week. You might also want the folder of icons, which you already used for the mouse tools tutorial.

You will also need the file CustomDialogTemplate.java for the last part of the tutorial. And you might want to keep a copy of that file around for making dialog boxes for your own programs.

The executable jar file DialogsComplete.jar contains a completed version of the program from this tutorial.


Standard Dialogs

Java has a number of easy-to-use standard dialog boxes. For example, the JColorChooser class defines a dialog box that allows the user to select a color. The class contains a static method

           JColorChooser.showDialog(component,title,currentColor);

that shows the dialog. This method does not return until the user selects a color or cancels the dialog. The method has a return value of type Color that tells you what color the user selected. The return value is null if the user canceled the dialog.

The parameters in JColorChooser.showDialog have the following meanings: The first parameter, component can be any component and is often given simply as this. The window that contains the given component becomes the "parent" of the dialog box. Every dialog box must have a parent window. You can specify the component as null, but in that case Java actually creates a hidden window to serve as the parent. The second parameter, title, is the string that will appear in the title bar of the dialog box. The third parameter, currentColor, is the Color that will be initially selected when the dialog box first opens. It represents a default value that will be selected if the user simply hits "OK". It looks like when curentColor is null, then white is the default value.

Several kinds of standard dialog are defined in the JOptionPane class, and this class has a number of static methods for showing dialog boxes. The simplest is

         JOptionPane.showMessageDialog(component,message);

which simply shows the message to the user and has no return value.

In the program Dialogs, the "Basic Message Dialog" and "Color Chooser" buttons are already implemented to show a message dialog and a color chooser dialog. Note that the message in the message dialog contains a line break. This is not automatic! If you want a line break in a message string, you have to include it yourself as a `\n'.

The response after the user selects a color shows one interesting fact about JOptionPane dialogs: the "message" in the dialog box does not have to be a string. In fact, the message can be any component. In this case, the message is a JLabel that has been configured to use the selected color as its foreground color.


Using JOptionPane

OK, time to make some dialogs yourself.

There are three different methods in JOptionPane for showing message dialogs, with different degrees of control over what's shown to the user. Besides the basic method, you can use

       JOptionPane.showMessageDialog(component,message,title,messageType);

where title is a string to be shown in the title bar of the dialog box and messageType is a code that determines what standard icon is shown in the box; it can be JOptionPane.ERROR_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.INFORMATION_MESSAGE, or JOptionPane.PLAIN_MESSAGE.

The third version of the method adds a fifth parameter, of type Icon, that specifies the icon to be shown in the dialog box. This allows you to replace the standard icon with a custom one.

Implement the "Full Message Dialog" button to show an ERROR or WARNING message. Use a custom icon from the icons directory if you want. For example, to load the file icons/icon11.png as a custom icon:

            ClassLoader cl = getClass().getClassLoader();
            Icon icon = new ImageIcon(cl.getResource("icons/icon11.png"));

JOptionPane also defines "confirm" dialogs and "input" dialogs. A confirm dialog contains a message and several buttons, and you can find out which button the user pressed. An input dialog has a text input box where the user can type a string, and you can find out the input. The basic methods for showing these dialog boxes are

         int resp = JOptionPane.showConfirmDialog(component,message);
         String input = JOptionPane.showInputDialog(component,message);

The return value from showConfirmDialog tells you which button the user clicked. For this basic form of the command, the butons are "Yes", "No" and "Cancel" and the possible return values are JOptionPane.YES_OPTION, JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION, and JOptionPane.CLOSED_OPTION. The last indicates that the user dismissed the dialog by clicking its close box rather than clicking one of the buttons.

The return value from showInputDialog is null if the user canceled the dialog. Otherwise, if the user clicked "OK", it's the content of the text input box (which can be an empty string, but not null).

Implement the "Input Dialog" and "Basic Confirm Dialog" buttons. In each case, test the return value to check whether the user canceled the dialog. If they didn't cancel, give some appropriate response.


The basic confirm dialog has an "OK" button and a "Cancel" button. You can get a different set of buttons by using a different form of the showConfirmDialog method:

      int resp = JOptionPane.showConfirmDialog(component,message,title,buttonType)

The last parameter, buttonType, tells what set of buttons to use. It can be JOptionPane.YES_NO_CANCEL_OPTION for the usual set of three buttons, JOptionPane.YES_NO_OPTION to provide only a "Yes" and a "No" button, or JOptionPane.OK_CANCEL_OPTION to use an "OK" and a "Cancel" button. When there is an "OK" button, the return value from the method can be JOptionPane.OK_OPTION. (Unfortunately, the user can still cancel a yes/no dialog by clicking on the dialog's close box, and in that case, the return value is JOptionPane.CLOSED_OPTION.)

Another version of the method allows you to also specify a messageType and an icon:

      int rest = JOptionPane.showConfirmDialog(component,message,
                                                 title,buttonType,messageType,icon)

Implement the "Full Confirm Dialog" button, using one of the more complex versions of the showConfirmDialog methods.


Adding a Custom Component

As mentioned above, the message in a JOptionPane dialog can be a component, which will be displayed in the message area of the dialog. You can, for example, design a complex panel containing a number of input components and use that panel as the message in a confirm dialog. After the user closes the dialog, you can inspect the contents of the panel to get the user's input.

As an example, you will implement the "Confirm Dialog with JComponent" button with a confirm dialog that gets both a minimum and a maximum value from the user. To make the panel, add the following class to Dialogs.java

            static class MinMaxPanel extends JPanel {
                JTextField min, max;
                MinMaxPanel() {
                    min = new JTextField(10);
                    max = new JTextField(10);
                    setLayout(new GridLayout(2,2,5,5));
                    add(new JLabel("Minimum Value = "));
                    add(min);
                    add(Box.createHorizontalStrut(10));
                    add(new JLabel("Maximum Value = "));
                    add(max);
                }
            }

Now, to implement "Confirm Dialog with JComponent", create a MinMaxPanel and use it in the showConfirmDialog method:

           MinMaxPanel panel = new MinMaxPanel();
           int resp = JOptionPane.showConfirmDialog(this, panel, 
                        "Enter the range of values", JOptionPane.OK_CANCEL_OPTION);

After you get the response, you can get the contents of the input boxes in the panel, panel.min.getText() and panel.max.getText(), and you can convert them into numbers using Double.parseDouble() or Integer.parseInteger() as usual. Of course, you should check whether the user clicked "OK" before doing that, and if the values are not legal you should show an error message -- and possibly show the dialog again.


Using JDialog Directly

Really, the only thing wrong with using a confirm dialog with a custom component is that the only way to respond to an error in the input is to show the dialog again. It's nicer to be able to put up an error message without closing the window. For that you have to create your own dialog from scratch. Dialogs are defined by subclasses of JDialog. They are almost identical to JFrames, except that a dialog has a parent window. (For example, if the parent window is disposed, the dialog will be as well.)

The class CustomDialogTemplate shows how to create modal dialogs as subclasses of JDialog. As is, it defines a simple dialog box for inputting one number. You can already use it for that purpose by calling

        Object ret = CustomDialogTemplate.showDialog(this, "Sample Dialog");

The return value is null if the user canceled the dialog, and it is (for the dialog as currently defined) an object of type Integer containing the user's input, if the user clicked OK. When the user clicks OK, the input is checked. If it's not legal, an error message is displayed and the dialog is not closed.

You can use the above call in your program to implement the "Roll-Your-Own JDialog" button. Better yet, if you want to do it, copy CustomDialogTemplate and modify it to do some other input, such as inputting both a minimum and a maximum value.