Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Abstract class for creating dialog boxes with OK/CANCEL/APPLY buttons.

0.00/5 (No votes)
17 Nov 2001 1  
An abstract base class that provides the basic plumbing necessary for an options dialog. More specifically, it manages the creation, layout, display and event handling of the three option buttons OK, APPLY and CANCEL.

Sample Image - JOptionsDialog.gif

Sample Image - JOptionsDialog.gif1

Introduction

A typical options dialog can be viewed as simply made up of two panes; a body pane where you show the UI components specific to your application, and a more generic options pane where the user can choose to save/discard the changes made and close the dialog box. (see screen shots above)

In addition, most options dialogs feature the dirty behavior. The dirty behavior defines two states; dirty and not dirty. When in the not dirty state (e.g. when the dialog is first initialized or when the apply button is clicked), the apply button is disabled and clicking on the OK button will simply close the dialog. When in the dirty state (e.g. when the user edits a text field or selects a check box), the apply button will be enabled and clicking on the OK button will cause the dialog's data model to be updated before closing the dialog.

JOptionsDialog is a simple abstract class that takes care of all the necessary plumbing works to get such a dialog box going. More specifically, it manages the creation, layout, display and event handling of the options pane, as well as the state of the dialog box (the dirty behavior). In addition, the user can choose to show any combination of the three available buttons, and/or change the alignment and dimensions of the buttons. Most of the features provided are configurable at compile-time or run-time. And if a feature cannot be configured, you can most certainly customize it in your sub-class.

Detailed API documentation of this class, as well as the sample dialog, is provided in both the demo and source zip packages. The source code of the sample dialog, in particular, can be a useful skeleton for building your own specialized dialogs.

Usage

To create your own options dialog, there are typically three things you need to do.

  1. extend your class from JOptionsDialog;
  2. implement the initialization of the UI components of the body pane in the abstract method initBodyPane();
  3. and finally, implement the data transfer mechanism between the body pane's UI components and the data model in the abstract method updateData(boolean).

Implementing the Body Pane

As mentioned above, the subclass should implement all initialization of the body pane's UI components in the abstract method initBodyPane(). This method does not take any arguments and returns a java.awt.Container object. The implementation should include the creation, layout and event handling setup of the body pane's UI components. Code snippet from the sample dialog's implementation is shown below:

Java
/**
 * Initializes the body pane. creates,
 * layout and set up the event handling
 * functions for the body pane's UI components.
 * @return a container that holds all
 * the dialog body components.
 */
protected Container initBodyPane() {
    //create button panel
        JPanel jpButtons = new JPanel();
        jpButtons.setLayout(new GridLayout(3,1));

        ... //other stuff

        m_jcbShowOK = new JCheckBox("Show OK");
        m_jcbShowOK.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setDirty();
                }
            }
        );
        jpButtons.add(m_jcbShowOK);

        ... //other stuff

        JPanel jpBody = new JPanel();
        jpBody.add(jpButtons, BorderLayout.WEST);

        ... //other stuff

        return jpBody;
}

In the code above, notice the call to the method setDirty() (a protected method implemented in JOptionsDialog) in the class attribute m_jcbShowOK's action listener. This sets the dialog state to dirty whenever the user clicks on the "Show OK" check box. It is the subclass' responsibility to call setDirty() at the appropriate times to set the dialog's state to dirty. Otherwise, the dialog will always remain in the not dirty state and the data entered by the user will never get transferred to the dialog's data model. The exception here is when the dialog's style is set to BEHAVE_DIRTY_ALWAYS (see later section on configuring the dialog), which causes the dialog to be permanently in the dirty state.

Implementing the data exchange between the data model and UI components

In a typical options dialog box, UI components (such as JTextField, JComboBox, etc ...) are used to receive user input which are then transferred to the data model. JOptionsDialog facilitates this mechanism through the abstract method updateData(boolean). This method takes a boolean argument which determines the direction of the data flow (i.e. if true, the data should be transferred from the UI components to the data model. And vice versa) and returns nothing. Code snippet from the sample dialog's implementation is shown below:

Java
/**
 * Updates the data model. To make things simple,
 * our model is simply a Properties
 * object. If toModel is true, we will write the data from the UI
 * components to the Properties object.
 * And vice versa. At the same time, we will
 * also update the dialog style.
 * @param toModel a flag which determines
 * the direction of the data flow. If
 * true, then the update should be
 * FROM UI components TO the data model.
 */
public void updateData(boolean toModel) {
    int flags = 0;

    if (toModel) //data transfer from Control to Model
    {
        //lets clear our model
        m_prop.clear();

        if (m_jcbShowOK.isSelected()) {
            flags |= OPTION_OK;
            m_prop.setProperty("OPTION_OK", "set");
        }

        ... //other stuff

    } else { //from Model to Control
        if (m_prop.getProperty("OPTION_OK")!= null) {
            flags |= OPTION_OK;
            m_jcbShowOK.setSelected(true);
        }

        ... //other stuff

    }

    ... //other stuff

}

Configuring JOptionsDialog

JOptionsDialog can be configured easily through the use of style flags. For a list of available styles and their descriptions, please refer to the javadoc. To configure the dialog's style, simply do a bitwise OR of the styles desired and pass the result to the method setDialogProperties(). To configure the dimension of the option buttons, use the method setButtonDimension(). The complete signature of these two methods are shown below:

Java
public void setDialogProperties(int flags, boolean shouldPack) {
... //other stuff
}

public void setButtonDimension(Dimension dim, boolean shouldPack) {
... //other stuff
}

The argument shouldPack instructs the method if it should call Window.pack() after setting the new styles. It will be slightly more efficient to pass in false when you have to configure the dialog several times (such as setting the button dimensions at the same time) before displaying it. In most cases, you will want to pass in true to show the updated styles immediately. Two convenient methods are provided for this purpose.

Java
public void setDialogProperties(int flags) {
    setDialogProperties(flags, true);
}

public void setButtonDimension(Dimension dim) {
    setButtonDimension(dim, true);
}

JOptionsDialog convenient functions

Java
public int doModal(){
... //other stuff
}

VC++ developers will most probably find this most familiar. Yep, the idea is definitely "borrowed" from the Microsoft Foundation Class library. Basically, this is a convenient method to show your option dialog in a modal loop and when the dialog closes, returns the ID of the option button that the user clicked.

Java
public void centerDialog(){
... //other stuff
}

This is a helper function to center the dialog box relative to its owner. If it doesn't have an owner or if the owner is not visible, then the dialog box is centered relative to the full screen. You may want to use the style flag DISPLAY_CENTER_DIALOG to center the dialog instead.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here