Main Page

Previous Next

Using Dialogs

A dialog is a window that is displayed within the context of another window – its parent. You use dialogs to manage input that can't be handled conveniently through interaction with the view: selecting from a range of options for instance, or enabling data to be entered from the keyboard. You can also use dialogs for information messages or warnings. The JDialog class in the javax.swing package defines dialogs, and a JDialog object is a specialized sort of Window. A JDialog object will typically contain one or more components for displaying information or allowing data to be entered, plus buttons for selection of dialog options (including closing the dialog), so there's quite a bit of work involved in putting one together. However, for many of the typical dialogs you will want to use, the JOptionPane class provides an easy shortcut to creating dialogs. Below is a dialog that we'll create later in this chapter using just one statement.

We'll use this dialog to provide a response to clicking on a Help/About menu item that we will add to Sketcher in a moment. First though, we need to understand a little more about how dialogs work.

Modal and Non-modal Dialogs

There are two different kinds of dialog that you can create, and they have distinct operating characteristics. You have a choice of creating either a modal dialog or a non-modal dialog. When you display a modal dialog – by selecting a menu item or clicking a button, it inhibits the operation of any other windows in the application until you close the dialog. The dialog opposite that displays a message is a modal dialog. The dialog window retains the focus as long as it is displayed and operation of the application cannot continue until you click the OK button. Modal dialogs that manage input will normally have at least two buttons, an OK button that you use to accept whatever input has been entered and then close the dialog, and a Cancel button to just close the dialog and abort the entry of the data. Dialogs that manage input are almost always modal dialogs, simply because you won't generally want to allow other interactions to be triggered until your user's input is complete.

A non-modal dialog can be left on the screen for as long as you want, since it doesn't block interaction with other windows in the application. You can also switch the focus back and forth between using a non-modal dialog and using any other application windows that are on the screen.

Whether you create a modal or a non-modal dialog is determined either by an argument to a dialog class constructor, or by which constructor you choose, since some of them create non-modal dialogs by default. The default, no-argument JDialog constructor creates a non-modal dialog with an empty title bar. Since you have no provision for specifying a parent window for the dialog, a shared hidden frame will be used as the parent in this case. You have a choice of five constructors for creating a JDialog object where the parent can be a window of type Frame or JFrame:

Constructor

Description

  
 

title bar

parent window

Mode

JDialog(Frame parent)

(empty)

parent

non-modal

JDialog(Frame parent, String title)

title

parent

non-modal

JDialog(Frame parent, boolean modal)

(empty)

parent

modal (when modal arg is true)

non-modal (when modal arg is false)

JDialog(Frame parent, String title, boolean modal)

title

parent

modal (when modal arg is true)

non-modal (when modal arg is false)

JDialog(Frame parent, String title, boolean modal, GraphicsConfiguration gc)

title

parent

modal (when modal arg is true)

non-modal (when modal arg is false)

Clearly since the first parameter is of type Frame, you can supply a reference of type Frame or type JFrame. There are a further five constructors for creating JDialog objects with a Dialog or JDialog object as the parent. The only difference between these and the ones in the table overleaf is that the type of the first parameter is Dialog rather than Frame. Any of these constructors can throw an exception of type HeadlessException if the system on which the code is executing does not have a display attached.

After you've created a JDialog object using any of the constructors, you can change the kind of dialog window it will produce from modal to non-modal, or vice versa, by calling the setModal()method for the object. If you specify the argument to the method as true, the dialog will be modal, and a false argument will make it non-modal. You can also check whether a JDialog object is modal or not. The isModal() method for the object will return true if it represents a modal dialog, and false otherwise.

All JDialog objects are initially invisible, so to display them you must call the setVisible() method for the JDialog object with the argument true. This method is inherited from the Component class via the Container and Window classes. If you call setVisible()with the argument false, the dialog window is removed from the screen. Once you've displayed a modal dialog window, the user can't interact with any of the other application windows until you call setVisible() for the dialog object with the argument false, so you typically do this in the event handler which is called to close the dialog. Note that the setVisible() method only affects the visibility of the dialog. You still have a perfectly good JDialog object so that when you want to display the dialog again, you just call its setVisible() method with an argument set to true. Of course, if you call dispose() for the JDialog object, or set the default close operation to DISPOSE_ON_CLOSE, then you won't be able to use the JDialog object again.

To set or change the title bar for a dialog, you just pass a String object to the setTitle() method for the JDialog object. If you want to know what the current title for a dialog is, you can call the getTitle()method which will return a String object containing the title bar string.

Dialog windows are resizable by default, so you can normally change the size of a dialog window by dragging its boundaries. If you don't want to allow a dialog window to be resized, you can inhibit this by calling the setResizable() for the JDialog object with the argument as false. An argument value of true re-enables the resizing capability.

A Simple Modal Dialog

The simplest kind of dialog is one that just displays some information. We could see how this works by adding a Help menu with an About menu item, and then displaying an About dialog to provide information about the application.

Let's derive our own dialog class from JDialog so we can create an About dialog.

Try It Out – Defining the AboutDialog Class

The constructor for our AboutDialog class will need to accept three arguments – the parent Frame object, which will be the application window in Sketcher, a String object defining what should appear on the title bar and a String object for the message we want to display. We'll only need one button in the dialog window, an OK button to close the dialog. We can make the whole thing self-contained by making the AboutDialog class the action listener for the button, and since it's only relevant in the context of the SketchFrame class, we can define it as an inner class.

public class SketchFrame extends Jframe implements Constants {
  // SketchFrame class as before...

  // Class defining a general purpose message box
  class AboutDialog extends JDialog implements ActionListener   {
    public AboutDialog(Frame parent, String title, String message)  {
      super(parent, title, true);
      // If there was a parent, set dialog position inside
      if(parent != null) {
        Dimension parentSize = parent.getSize();     // Parent size
        Point p = parent.getLocation();              // Parent position
        setLocation(p.x+parentSize.width/4,p.y+parentSize.height/4); 
      }

      // Create the message pane
      JPanel messagePane = new JPanel();
      messagePane.add(new JLabel(message));        
      getContentPane().add(messagePane);

      // Create the button pane
      JPanel buttonPane = new JPanel();
      JButton button = new JButton("OK");        // Create OK button
      buttonPane.add(button);                    // add to content pane
      button.addActionListener(this);
      getContentPane().add(buttonPane, BorderLayout.SOUTH);
      setDefaultCloseOperation(DISPOSE_ON_CLOSE);
      pack();                                    // Size window for components
      setVisible(true);
    }

    // OK button action
    public void actionPerformed(ActionEvent e)  {
      setVisible(false);                         // Set dialog invisible
      dispose();                                 // Release the dialog resources
    }
  }
}

How It Works

The constructor first calls the base JDialog class constructor to create a modal dialog with the title bar given by the title argument. It then defines the position of the dialog relative to the position of the frame.

Important 

When we create an instance of the AboutDialog class in the Sketcher program a little later in this chapter, we'll specify the SketchFrame object as the parent for the dialog. The parent relationship between the application window and the dialog implies a lifetime dependency. When the SketchFrame object is destroyed, the AboutDialog object will be too, because it is a child of the SketchFrame object. This doesn't just apply to JDialog objects – any Window object can have another Window object as a parent.

By default the AboutDialog window will be positioned relative to the top-left corner of the screen. To position the dialog appropriately, we set the coordinates of the top-left corner of the dialog as one quarter of the distance across the width of the application window, and one quarter of the distance down from the top-left corner of the application window.

You add the components you want to display in a dialog to the content pane for the JDialog object. The content pane has a BorderLayout manager by default, just like the content pane for the application window, and this is quite convenient for our dialog layout. The dialog contains two JPanel objects that are created in the constructor, one to hold a JLabel object for the message that is passed to the constructor, and the other to hold the OK button that will close the dialog. The messagePane object is added so that it fills the center of the dialog window. The buttonPane position is specified as BorderLayout.SOUTH, so it will be at the bottom of the dialog window. Both JPanel objects have a FlowLayout manager by default.

We want the AboutDialog object to be the listener for the OK button so we pass the this variable as the argument to the addActionListener()method call for the button.

The pack()method is inherited from the Window class. This method packs the components in the window, setting the window to an optimal size for the components it contains. Note that if you don't call pack() here, the size for your dialog will not be set and you won't be able to see it.

The actionPerformed()method will be called when the OK button is selected. This just disposes of the dialog by calling the dispose() method for the AboutDialog object so the dialog window will disappear from the screen and the resources it was using will be released.

To add a Help menu with an About item to our Sketcher application, we need to insert some code into the SketchFrame class constructor.

Try It Out – Creating an About Menu Item

You shouldn't have any trouble with this. We can make the SketchFrame object the listener for the About menu item so add ActionListener to the list of interfaces implemented by SketchFrame:

public class SketchFrame extends JFrame implements Constants, ActionListener {

The changes to the constructor to add the Help menu will be:

  public SketchFrame(String title , Sketcher theApp) {
    setTitle(title);                           // Set the window title
    this.theApp = theApp;
    setJMenuBar(menuBar);                      // Add the menu bar to the window
    setDefaultCloseOperation(EXIT_ON_CLOSE);   // Default is exit the application

    JMenu fileMenu = new JMenu("File");        // Create File menu
    JMenu elementMenu = new JMenu("Elements"); // Create Elements menu
    JMenu helpMenu = new JMenu("Help");           // Create Help menu
    fileMenu.setMnemonic('F');                    // Create shortcut
    elementMenu.setMnemonic('E');                 // Create shortcut
    helpMenu.setMnemonic('H');                    // Create shortcut 

    // All the stuff for the previous menus and the toolbar, as before...

    // Add the About item to the Help menu
    aboutItem = new JMenuItem("About");           // Create the item
    aboutItem.addActionListener(this);            // Listener is the frame
    helpMenu.add(aboutItem);                      // Add item to menu
    menuBar.add(helpMenu);                        // Add the Help menu
  }

Add aboutMenu as a private member of the SketchFrame class:

  // Sundry menu items
  private JMenuItem aboutItem;

Lastly, we need to implement the method in the SketchFrame class to handle the About menu item's events:

  // Handle About menu action events
  public void actionPerformed(ActionEvent e)  {
    if(e.getSource() == aboutItem)
    {
      // Create about dialog with the app window as parent
      AboutDialog aboutDlg = new AboutDialog(this, "About Sketcher",
                                           "Sketcher Copyright Ivor Horton 2001");
    }
  }

You can now recompile SketchFrame.java to try out our smart new dialog.

The dialog pops up when you select the About item in the Help menu. Until you select the OK button in the About Sketcher dialog, you can't interact with the application window at all since we created this as a modal dialog. By changing the last argument in the call to the superclass constructor in the AboutDialog constructor, you can make it non-modal and see how that works. This kind of dialog is usually modal though.

If you resize the application window before you display the About dialog, you'll see that its position of the dialog relative to the application window is adjusted accordingly.

How It Works

This is stuff that should be very familiar by now. We create a JMenu object for the Help item on the menu bar, and add a shortcut for it by calling its setMnemonic() member. We create a JMenuItem object which is the About menu item and call its addActionListener()method to make the SketchFrame object the listener for the item. After adding the menu item to the Help menu, we add the helpMenu object to the menubar object.

We create an AboutDialog object in the actionPerformed() method for the SketchFrame object, as this will be called when the About menu item is clicked. Before we display the dialog, we verify that the source of the event is the menu item, aboutItem. This is not important now, but we will add other menu items later, and we will want to handle their events using the same actionPerformed() method. The dialog object is self-contained and disposes of itself when the OK button is clicked. The dialog that we want to display here will always display the same message, so there's no real point in creating and destroying it each time we want to display it. You could arrange for the dialog box object to be created once, and the reference stored as a member of the SketchFrame class. Then you make it visible in the actionPerformed() method for the menu item and make it invisible in the actionPerformed() method responding to the dialog OK button event.

This is all very well, but it was a lot of work just to get a dialog with a message displayed. Deriving a class from JDialog gives you complete flexibility as to how the dialog works, but we didn't really need it in this case. Didn't we say there was an easier way?

Previous Next
JavaScript Editor Java Tutorials Free JavaScript Editor


One of best app developer nix solutions more on this site . ebay.com