All Categories :
Java
Chapter 20
Menus, Buttons, and Dialong
Boxes
CONTENTS
This chapter covers the details of using the Menu, Button,
and Dialog classes. It describes the available menu and
button options and shows you how to quickly and easily construct
menus and buttons for your window programs. The use of dialog
boxes is explained, and a generic MessageDialog component
is constructed and explained as part of an example. When you finish
this chapter, you will be able to effectively use menus, buttons,
and dialog boxes in your Java window programs.
Java provides a rich set of menu-related classes to create and
interact with pull-down menus. The MenuComponent class
is the superclass of all menu-related classes. It extends the
Object class. The getFont() and setFont()
methods are the most useful methods provided by MenuComponent.
Its two direct superclasses, MenuBar and MenuItem,
provide most of the methods for creating and using menus. The
CheckboxMenuItem class extends the MenuItem
class and supports menu items that can be checked on or off. The
Menu class extends the MenuItem class and implements
a collection of MenuItem objects that can be assigned
to a MenuBar object.
You are probably somewhat familiar with menus from Chapters 18,
"Opening Windows," and 19, "Organizing
Window Programs." A program's application window is implemented
by a Frame object. It can have one and only one MenuBar
object, which is set using the setMenuBar() method. A
menu bar is a collection of menus. Each menu is represented
as a separate pull-down menu on the menu bar. Common examples
are the File, Edit, and Help pull-down menus found in many window
applications. The MenuBar class allows a special menu
to be designated as a Help menu, but this feature is not implemented
in Windows 95 or NT.
A Menu object contains one or more MenuItem
objects, which can be a normal user-selectable MenuItem
object, a CheckboxMenuItem object, or another Menu
object. Java supports tear-off menus, which are menus that
can be removed from a menu bar. A tear-off menu is constructed
in the same manner as a regular menu-you only need to set the
boolean tear-off value in the Menu() constructor.
Tear-off menus, however, are not implemented within Windows 95
or NT.
The MenuItem class is the superclass of the Menu
class. It allows a menu to be a menu item and is used in constructing
cascading, multilevel menus. MenuItem is also the superclass
of the CheckboxMenuItem class and provides the capability
to implement menu items that can be checked or unchecked. If a
MenuItem object is constructed directly with the MenuItem
constructor, it becomes a normal menu item that is selected from
a pull-down menu.
The creation and organization of menu bars, menus, and menu items
into a program's menu is a straightforward, but tedious, process.
You have to create a menu bar, create and add menus to the menu
bar, add menu items to the menus, and then add the menu bar to
the program's application window. This usually involves the use
of a large number of constructors and access methods. To illustrate
the use of the menu-related classes and to simplify the menu-creation
process, you'll create two classes, MyMenu and MyMenuBar,
that can be used to quickly construct menus for Java programs.
These classes implement multiple levels of menus, checkbox menu
items, and menu-disabling options. The special Help menu and tear-off
menus are not implemented, however, because they are transparent
to Windows 95 and NT.
The MyMenu class is used to construct menus using an
array of objects consisting of String objects that represent
menu labels, or arrays of objects that represent submenus. Menu
labels can be either checkbox menu items or normal menu items
and can be either initially enabled or disabled (grayed out).
Checkbox menu items can be initially checked or unchecked. The
first character of the label's text string is used to indicate
what type of label it is. The character conventions are as follows:
+
|
A checkbox menu item that is initially checked and enabled.
|
#
|
A checkbox menu item that is initially checked and disabled.
|
-
|
A checkbox menu item that is initially unchecked and enabled. If the label consists of just -, it indicates a separator.
|
=
|
A checkbox menu item that is initially unchecked and disabled.
|
~
|
A normal menu item that is initially disabled.
|
|
Any other character indicates a normal, enabled menu item. If the first character is !, it is ignored. This allows any menu item to begin with any character.
|
These conventions apply to menu options. Only the ~ and
! options are used with the menu's main label. Using
these options greatly simplifies the process of a menu creation.
The source code for the MyMenu class is shown in Listing
20.1.
Listing 20.1. The source code of the MyMenu
class.
package jdg.ch20;
import java.awt.*;
public class MyMenu extends Menu {
public MyMenu(Object labels[]) {
super((String)labels[0]);
String menuName = (String) labels[0];
char firstMenuChar = menuName.charAt(0);
if(firstMenuChar == '~' || firstMenuChar =='!'){
setLabel(menuName.substring(1));
if(firstMenuChar == '~') disable();
}
for(int i=1;i<labels.length;++i) {
if(labels[i] instanceof String){
if("-".equals(labels[i])) addSeparator();
else{
String label = (String)labels[i];
char firstChar = label.charAt(0);
switch(firstChar){
case '+':
CheckboxMenuItem checkboxItem
= new CheckboxMenuItem(label.substring(1));
checkboxItem.setState(true);
add(checkboxItem);
break;
case '#':
checkboxItem = new CheckboxMenuItem(label.substring(1));
checkboxItem.setState(true);
checkboxItem.disable();
add(checkboxItem);
break;
case '-':
checkboxItem = new CheckboxMenuItem(label.substring(1));
checkboxItem.setState(false);
add(checkboxItem);
break;
case '=':
checkboxItem = new CheckboxMenuItem(label.substring(1));
checkboxItem.setState(false);
checkboxItem.disable();
add(checkboxItem);
break;
case '~':
MenuItem menuItem = new MenuItem(label.substring(1));
menuItem.disable();
add(menuItem);
break;
case '!':
add(label.substring(1));
break;
default:
add(label);
}
}
}else{
add(new MyMenu((Object[])labels[i]));
}
}
}
public MenuItem getItem(String menuItem) {
int numItems = countItems();
for(int i=0;i<numItems;++i)
if(menuItem.equals(getItem(i).getLabel())) return
getItem(i);
return null;
}
}
The MyMenu class specifies that it is in the package
jdg.ch20. Make sure that you place it in the jdg/ch20
directory and compile it. You'll be using it quite a bit in subsequent
chapters.
MyMenu contains no field variables. It consists of a
single constructor and the getItem() access method. The
getItem() method retrieves a menu item contained in the
menu and based on the menu item's label. It uses the countItems()
and getItem() methods of the Menu class to retrieve
the menu items contained in a menu and the getLabel()
method of the MenuItem class to match a menu item with
the search string.
The MyMenu constructor constructs a menu from an array
of menu labels and nested menu arrays (representing submenus).
For example, to construct a typical File menu, labeled File, with
the New and Open menu items followed by a separator and an Exit
menu item, you would use the following MyMenu constructor:
String fileMenuLabels[] = {"File","New","Open","-","Exit"};
MyMenu fileMenu = new MyMenu(fileLabelMenus);
The first object in the array must be a String object
that is the main label associated with the menu. The following
objects are either String objects identifying the labels
of the menu items contained in the menu, separators, or second-level
arrays representing submenus. For example, the following creates
a multilevel menu:
String goMenuLabels[] = {"Go","Beginning","End","Previous","Next"};
String editMenuLabels[] = {"Edit","Copy","Cut","-","Paste","-",goMenuLabels};
MyMenu editLabel = new MyMenu(editMenuLabels);
Using the MyMenu class is much easier than constructing
each of the individual menu items and adding them to a menu.
Let's step through the MyMenu constructor to see how
it works. It uses the super() class constructor call
statement to construct a Menu object using the first
label in the labels[] array. This label may contain the
~ or ! character as the first character. MyMenu()
checks for these characters and readjusts the menu's label accordingly.
If the first character of the menu's label is ~, MyMenu()
will disable the entire menu using the disable() method
of the MenuItem class.
After setting up the menu's main label, MyMenu() iterates
through the list of objects contained in labels[]. If
the object is an instance of the String class, and is
therefore a label, MyMenu() checks the first letter of
the label and processes it accordingly. If the object is not an
instance of the String class, MyMenu() calls
itself again, passing the object to itself as another array of
objects. It then adds the resulting MyMenu object to
itself using the add() method of the Menu class.
This allows submenus to be processed in a recursive fashion.
MyMenu() processes the menu item labels by using a switch
statement to check the first character of the label to see if
it matches the +, #, -, =,
~, or ! character. If it does not match any
of these characters, the label is added as a normal menu item.
If the label equals -, a separator is added.
If the first character is +, an enabled and checked CheckboxMenuItem
object is added to the menu. The setState() method of
the CheckboxMenuItem class is used to set the state of
the menu item to checked. If the first character is #,
a checked, but disabled, CheckboxMenuItem object is added.
The disable() method of the MenuItem class is
used to disable the menu item. The cases in which the first character
of the label is - or = are processed in a similar
manner, except that the CheckboxMenuItem object is initially
unchecked.
When the first character of the label is ~, a normal
MenuItem object is added to the menu. The menu item is
disabled.
The ! character is an escape character that is used to
create a normal menu item beginning with any of the special characters
previously mentioned. When the first character of a label is !,
the actual label generated begins with the subsequent character.
The MyMenuBar class uses the MyMenu class presented
in the previous section to quickly create an entire menu bar.
Whereas the MyMenu class uses an array of labels and
submenus to create a menu, the MyMenuBar class uses an
array of these arrays to create the entire menu bar. For example,
the following statements will construct a menu bar with File,
Edit, and Help menus, each consisting of individual menu items:
String menuBarLabels[] = {
{"File","New","Open","-","~Save
As","-","Exit"};
{"Edit","Copy","Cut","-","~Paste"};
{"Help","Index"};
};
MyMenuBar menuBar = new MyMenuBar(menuBarLabels);
Note that the Save As and Paste menu items are initially disabled.
The source code of the MyMenuBar class is shown in Listing
20.2.
Listing 20.2. The source code of the MyMenuBar
class.
package jdg.ch20;
import java.awt.*;
public class MyMenuBar extends MenuBar {
public MyMenuBar(Object labels[][]) {
super();
for(int i=0;i<labels.length;++i)
add(new MyMenu(labels[i]));
}
public MyMenu getMenu(String menuName) {
int numMenus = countMenus();
for(int i=0;i<numMenus;++i)
if(menuName.equals(getMenu(i).getLabel())) return((MyMenu)getMenu(i));
return null;
}
}
The MyMenuBar constructor simply iterates through the
outer array and passes the first-level elements (which are themselves
Object arrays) to the MyMenu constructor to
construct MyMenu objects. These objects are then added
to the MyMenuBar object being constructed using the add()
method inherited from the MenuBar class.
The getMenu() method retrieves a MyMenu object
from a MyMenuBar object based on the label associated
with the MyMenu object. It uses the CountMenus()
and getMenu() methods of the MenuBar class to
retrieve each MyMenu object contained in the menu bar.
The getLabel() method of the MenuItem class
is used to check the labels of the MyMenu objects against
the search string.
The MenuApp program illustrates the use of the MyMenuBar
and MyMenu classes. Its source code is shown in Listing
20.3.
Listing 20.3. The source code of the MenuApp
program.
import java.awt.*;
import jdg.ch20.MyMenu;
import jdg.ch20.MyMenuBar;
public class MenuApp extends Frame {
MyMenuBar menuBar;
public static void main(String args[]){
MenuApp app = new MenuApp();
}
public MenuApp() {
super("Menu Madness");
setup();
pack();
resize(400,400);
show();
}
void setup() {
setBackground(Color.white);
setupMenuBar();
}
void setupMenuBar(){
String gotoMenu[] = {"Go To","Beginning","End","-","Line
Number"};
Object menuItems[][] = {
{"File","New","Open","-","~Save","~Save
As","-","Exit"},
{"Edit","Copy","Cut","-","~Paste"},
{"Search","Find","~Find
Next","~Find Previous","-", gotoMenu},
{"View","-Hex","+Line
Number","+Column Number"},
{"Help","About Menu Madness"},
};
menuBar = new MyMenuBar(menuItems);
setMenuBar(menuBar);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
System.exit(0);
return true;
}else if(event.id==Event.ACTION_EVENT){
if(event.target instanceof MenuItem){
if("Exit".equals(event.arg)){
System.exit(0);
return true;
}else if("New".equals(event.arg)
|| "Open".equals(event.arg)){
menuBar.getMenu("File").getItem("Save").enable();
menuBar.getMenu("File").getItem("Save
As").enable();
return true;
}else if("Copy".equals(event.arg)
|| "Cut".equals(event.arg)){
menuBar.getMenu("Edit").getItem("Paste").enable();
return true;
}else if("Find".equals(event.arg)){
menuBar.getMenu("Search").getItem("Find
Next").enable();
menuBar.getMenu("Search").getItem("Find
Previous").enable();
return true;
}else if("Hex".equals(event.arg)){
CheckboxMenuItem hexMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Hex");
CheckboxMenuItem lineMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Line
Number");
CheckboxMenuItem colMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Column
Number");
boolean hexState = hexMenuItem.getState();
lineMenuItem.setState(!hexState);
colMenuItem.setState(!hexState);
return true;
}else if("Line Number".equals(event.arg)
||
"Column Number".equals(event.arg)){
CheckboxMenuItem hexMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Hex");
CheckboxMenuItem lineMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Line
Number");
CheckboxMenuItem colMenuItem =
(CheckboxMenuItem) menuBar.getMenu("View").getItem("Column
Number");
boolean lineState = lineMenuItem.getState();
boolean columnState = colMenuItem.getState();
hexMenuItem.setState(!(lineState
| columnState));
return true;
}else if("About Menu Madness".equals(event.arg)){
menuBar.getMenu("Help").disable();
return true;
}
}
}
return false;
}
}
MenuApp shows how the MyMenuBar and MyMenu
classes are used to easily create a menu bar and to support the
processing of menu-related events. When the program is executed,
it displays a blank opening screen and a menu bar with five pull-down
menus, as shown in Figure 20.1.
Figure 20.1 : The MenuApp opening window.
Click on the File menu and select the New menu item as shown in
Figure 20.2. This will cause the Save
and Save As menu items to become enabled. You can verify this
by clicking on the File menu once again.
Figure 20.2 : The File menu.
Click on the Edit menu and select the Copy menu item as shown
in Figure 20.3. This results in the Paste
menu item becoming enabled.
Figure 20.3 : The Edit menu.
Click on the Search menu and then on the Go To menu item as shown
in Figure 20.4. The Go To menu item is
a second-level menu that is attached to the Search menu.
Figure 20.4 : The Search menu.
Click on the View menu and select the Hex checkbox menu item as
shown in Figure 20.5. Notice that the
Line Number and Column Number menu items that are initially checked
become unchecked, as shown in Figure 20.6.
Figure 20.5 : The View menu.
Figure 20.6 : The View menu after checking Hex.
Click on the Help menu and select About Menu Madness, as shown
in Figure 20.7. This Help menu isn't
much help at all because it is programmed to disable itself, as
shown in Figure 20.8.
Figure 20.7 : The Help Menu.
Figure 20.8 : The Help menu disabled.
You've completed the tour of the MenuApp program. Select
Exit from the File menu to terminate the program's operation.
Inside MenuApp
The MenuApp class consists of a single field variable,
menuBar, that is an object of class MyMenuBar.
The MenuApp constructor creates a 400¥400
frame window with the title Menu Madness and invokes the setup()
method to set up the background color and the menu bar. The setup()
method invokes setupMenuBar() to actually perform the
menu bar setup.
The setupMenuBar() method creates a gotoMenu[]
array as the labels of a submenu that will be attached to the
Search menu. The menuItems[][] array is used to define
the labels associated with the menu bar and its first-level menus.
The gotoMenu[] array is included as an object in this
array. Notice the use of the first-character conventions for disabling
menu items and specifying menu items that are checkboxes. The
menu bar is created, assigned to the menuBar variable,
and set as the menu bar for the MenuApp frame.
Creating the menu bar was a snap using the MyMenuBar
class. However, creating the menu bar is only half the work. You
also need to write event-handling code that acts on the menu items
selected by the user. The event-handling code of MenuApp
is used to illustrate the use of the various methods provided
with menus and menu items.
The WINDOWS_DESTROY event and the Exit menu item are
handled by terminating the program's execution. The New and Open
menu items cause the Save and Save As menu items to be enabled.
The getMenu() method of MyMenuBar and the getItem()
method of MyMenu are used to retrieve the Save and Save
As MenuItem objects. The enable() method of
the MenuItem class is used to enable these menu items.
Note that the Save and Save As menu items, as well as some other
menu items, are not handled. Selecting these menu items results
in no action being performed by MenuApp.
The Copy and Cut menu items are processed in a similar manner
as the New and Open menu items. Selecting Copy or Cut menu items
results in the Paste menu item being enabled.
The Find menu item causes the Find Next and Find Previous menu
items to be enabled.
The Hex checkbox menu item is handled by using the getState()
method to determine the state of its associated checkbox and then
setting the checkbox state of the Line Number and Column Number
checkbox menu items to the opposite state.
The Line Number and Column Number menu items are set and reset
independent of each other, but they are combined to determine
the state of the Hex menu item. If both the Line Number and Column
Number menu items are unchecked, the state of the Hex menu item
is set to checked. Otherwise, the Hex menu item is set to unchecked.
The handling of the About Menu Madness menu item shows how an
entire menu can be disabled.
Buttons are one of the easiest GUI components to use in a Java
window program. You create them using the Button constructor
and add them to your program using the add() method of
their container. After that, you just handle the events associated
with them and, optionally, change their labels.
To do something a little bit creative with labels, you can design
a ButtonBar class. This class creates a dialog box with
a specified label and adds a list of buttons to the dialog box,
in the form of a button bar. It also allows the buttons in the
button bar to be arranged in a vertical or horizontal fashion.
The source code for the ButtonBar class is shown in Listing
20.4.
Listing 20.4. The source code of the ButtonBar
class.
package jdg.ch20;
import java.awt.*;
public class ButtonBar extends Dialog {
public static int HORIZONTAL = 0;
public static int VERTICAL = 1;
public ButtonBar(Frame parent,String title,String labels[],int
orientation) {
super(parent,title,false);
int length = labels.length;
if(orientation == HORIZONTAL) setLayout(new GridLayout(1,length));
else setLayout(new GridLayout(length,1));
for(int i=0;i<length;++i) add(new Button(labels[i]));
pack();
resize(minimumSize());
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY) show(false);
return false;
}
}
The HORIZONTAL and VERTICAL constants are used
to specify the orientation of the button bar. The constructor
uses the parent, title, labels[], and
orientation parameters. The parent and title
parameters are passed to the Dialog class constructor
via the super() constructor call statement. The false
value indicates that the button bar is not modal. The orientation
parameter is used to determine the type of GridLayout
associated with the button bar. After the orientation is specified,
the Button objects, whose labels are specified by the
labels[] array, are added to the button bar. The button
bar dialog box is then packed and resized to the minimum size
needed to contain the buttons.
A single event is handled by the ButtonBar class. The
WINDOWS_DESTROY event is generated when a user tries
to close the button bar dialog box. When this happens, the show()
method inherited from the Window class is used to hide
the dialog box. The handleEvent() method returns the
false value, allowing the event to be processed by the
window containing the dialog box.
The ButtonApp program illustrates the operation of the
ButtonBar class. Its source code is shown in Listing
20.5.
Listing 20.5. The source code of the ButtonApp
program.
import java.awt.*;
import jdg.ch20.MyMenu;
import jdg.ch20.MyMenuBar;
import jdg.ch20.ButtonBar;
public class ButtonApp extends Frame {
MyMenuBar menuBar;
ButtonBar buttonBar;
public static void main(String args[]){
ButtonApp app = new ButtonApp();
}
public ButtonApp() {
super("ButtonApp");
setup();
pack();
resize(400,400);
show();
}
void setup() {
setBackground(Color.white);
setupMenuBar();
String buttons[] = {"this","is","a","test"};
buttonBar = new ButtonBar(this,"Button Bar",buttons,ButtonBar.HORIZONTAL);
}
void setupMenuBar(){
Object menuItems[][] = {
{"File","Exit"},
{"View","-Button Bar"},
};
menuBar = new MyMenuBar(menuItems);
setMenuBar(menuBar);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
if(event.target instanceof ButtonBar){
CheckboxMenuItem buttonItem =
(CheckboxMenuItem)menuBar.getMenu("View").getItem("Button
Bar");
buttonItem.setState(false);
return true;
}
System.exit(0);
return true;
}else if(event.id==Event.ACTION_EVENT){
if(event.target instanceof MenuItem){
if("Exit".equals(event.arg)){
System.exit(0);
return true;
}else if("Button Bar".equals(event.arg)){
CheckboxMenuItem buttonItem =
(CheckboxMenuItem)menuBar.getMenu("View").getItem("Button
Bar");
boolean viewButtonBar = buttonItem.getState();
buttonBar.show(viewButtonBar);
return true;
}
}
}
return false;
}
}
When you execute ButtonApp, it displays the opening window
shown in Figure 20.9.
Figure 20.9 : The ButtonApp opening window.
Select Button Bar from the View menu, as shown in Figure 20.10.
Figure 20.10 : Selecting Button Bar from the View menu.
The button bar shown in Figure 20.11
is displayed on top of the main ButtonApp window. If
you select the View menu once more, you will notice that the Button
Bar menu item is implemented as a pull-down menu. It is checked
or unchecked depending on whether the button bar is displayed.
Figure 20.11 : The button bar.
The ButtonApp program consists mostly of setup and event-handling
software. It declares two field variables, menuBar and
buttonBar, that are used to reference the program's menu
bar and the button bar. The constructor follows the typical approach
to constructing a frame window and creates a 400¥400
window with the ButtonApp title.
The setup() method sets the background to white, creates
a menu bar using the MyMenuBar class, and constructs
a horizontal button bar using the ButtonBar class constructor
introduced in the previous section. The rest of the program consists
of event handling.
The WINDOW_DESTROY event is handled a little differently
than the typical approach. Remember that this event can be generated
for the main application window or for the button bar dialog box.
The event.target variable is checked to see if the event
was generated for an instance of the ButtonBar class.
If so, the checkbox associated with the Button Bar menu is unchecked.
If the WINDOW_DESTROY event was generated for the main
application window or the Exit menu item is selected, the program
is terminated.
If the Button Bar menu item is selected, the state of the checkbox
associated with that menu item is used to determine whether the
button bar should be displayed. The show() method inherited
from the Component class is used to turn the button bar
display on and off.
The ButtonBar class illustrates some of the typical methods
used with dialog boxes. Most of these methods are not specific
to the Dialog class, which provides few methods of its
own. Rather, they are inherited from the Window and Component
classes, which are superclasses of the Dialog class.
The Dialog class is used to construct a window that is
displayed separately from the application menu. The window associated
with a Dialog object is not allowed to contain a menu
bar. It may be specified as being modal, meaning that it
is displayed on top of the main application window until it is
hidden or disposed of using the show() and dispose()
methods. Most dialog boxes are not as elaborate as that made with
the ButtonBar class. They are mainly used to display
information to the user and get the user's response via a button
click.
The MessageDialog class provides a custom component that
implements the most common types of dialog boxes. It provides
a convenient constructor for creating dialog boxes and partially
handles the WINDOW_DESTROY event by hiding a dialog box
from view. The source code is shown in Listing 20.6.
Listing 20.6. The source code of the MessageDialog
class.
package jdg.ch20;
import java.awt.*;
public class MessageDialog extends Dialog {
public MessageDialog(Frame parent,String title,boolean modal,String
text[],
String buttons[]) {
super(parent,title,modal);
int textLines = text.length;
int numButtons = buttons.length;
Panel textPanel = new Panel();
Panel buttonPanel = new Panel();
textPanel.setLayout(new GridLayout(textLines,1));
for(int i=0;i<textLines;++i) textPanel.add(new
Label(text[i]));
for(int i=0;i<numButtons;++i) buttonPanel.add(new
Button(buttons[i]));
add("North",textPanel);
add("South",buttonPanel);
setBackground(Color.lightGray);
setForeground(Color.white);
pack();
resize(minimumSize());
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY) show(false);
else if(event.id==Event.ACTION_EVENT && event.target
instanceof Button)
show(false);
return false;
}
}
The MessageDialog constructor uses the parent,
title, modal, text[], and buttons[]
parameters. The parent, title, and modal
parameters are passed to the Dialog constructor of its
parent class. Two Panel objects are created and assigned
to textPanel and buttonPanel. The textPanel
layout is specified as a GridLayout object and the buttonPanel
layout is the default FlowLayout object. The text[]
lines are arranged in a vertical grid in the textPanel.
The buttons[] are laid out in a centered horizontal fashion
within the buttonPanel. The layout for the MessageDialog
object is BorderLayout, by default. The textPanel
is added to the top of the dialog box and the buttonPanel
is added to the bottom. The foreground and background colors are
set to light gray and white. The dialog box is packed and resized
to the minimum size needed to contain the two panels.
The MessageApp program shows how the MessageDialog
class can be used to implement traditional dialog box functions
found in typical window programs. Its source code is shown in
Listing 20.7.
Listing 20.7. The source code of the MessageApp
program.
import java.awt.*;
import jdg.ch20.MyMenu;
import jdg.ch20.MyMenuBar;
import jdg.ch20.MessageDialog;
public class MessageApp extends Frame {
MyMenuBar menuBar;
MessageDialog dialog;
public static void main(String args[]){
MessageApp app = new MessageApp();
}
public MessageApp() {
super("MessageApp");
setup();
pack();
resize(400,400);
show();
}
void setup() {
setBackground(Color.white);
setupMenuBar();
}
void setupMenuBar(){
Object menuItems[][] = {
{"File","Exit"},
{"View","Information","Confirmation","Selection"},
};
menuBar = new MyMenuBar(menuItems);
setMenuBar(menuBar);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
if(event.target instanceof MessageDialog) return
true;
System.exit(0);
return true;
}else if(event.id==Event.ACTION_EVENT){
if(event.target instanceof MenuItem){
if("Exit".equals(event.arg)){
System.exit(0);
return true;
}else if("Information".equals(event.arg)){
String text[] = {"Don't look
now, but your shoelace is untied."};
String buttons[] = {"OK"};
dialog = new MessageDialog(this,"Information",true,text,buttons);
dialog.show();
return true;
}else if("Confirmation".equals(event.arg)){
String text[] = {"Do you really
want to do this?"};
String buttons[] = {"Yes","No","Cancel"};
dialog = new MessageDialog(this,"Confirmation",true,text,buttons);
dialog.show();
return true;
}else if("Selection".equals(event.arg)){
String text[] = {"What direction
do you want to go?",
"North: cold", "South:
warm", "East: humid", "West: arid"};
String buttons[] = {"North","South","East","West"};
dialog = new MessageDialog(this,"Selection",true,text,buttons);
dialog.show();
return true;
}
}
}
return false;
}
}
The MessageApp opening window is shown in Figure 20.12.
It supports the File and View pull-down menus.
Figure 20.12 : The MessageApp opening windows.
Select the Information menu item from the View pull-down menu,
as shown in Figure 20.13.
Figure 20.13 : Selecting Information from the View menu.
A helpful Information dialog box is displayed, as shown in Figure 20.14.
This type of dialog box is typically used to provide information
to the user. When the dialog box is displayed, the user acknowledges
the information by clicking on the OK button.
Figure 20.14 : The Information dialog box.
Selecting Confirmation from the View menu results in a Confirmation
dialog box being displayed to the user, as shown in Figure 20.15.
This type of dialog box requests confirmation from the user before
attempting to perform an operation that may require the user's
approval. If the user clicks the Yes button, the action is performed.
If the user clicks No, the operation is not performed. If the
user clicks Cancel, an entire series of actions leading up to
the confirmation dialog box is aborted.
Figure 20.15 : The Confirmation dialog box.
Choosing the Selection menu item from the View menu results in
a multiple-choice Selection dialog box displayed to the user.
The user is allowed to pick one from several alternative paths
of program execution. (See Figure 20.16.)
Figure 20.16 : The Selection dialog box.
The MessageApp constructor creates a 400¥400
window, titled MessageApp. It uses the MyMenuBar class
to construct the program's menu bar. No special processing of
note is performed in the application window's construction. The
dialog boxes, previously shown, are created by the program's event-handling
software.
The handleEvent() method takes the message dialog boxes
into account when processing the WINDOW_DESTROY message.
It checks to see if the target of the event is a dialog box and,
if so, continues with program execution. If the Information menu
item is selected, a new MessageDialog object is created
with the information shown in Figure 20.14
and the dialog box is displayed to the user using the show()
method. The dialog box is modal. The Confirmation and Selection
menu items are handled in a similar manner. They create the dialog
boxes shown in Figures 20.15 and 20.16
using the MessageDialog() constructor.
The FileDialog class is a custom subclass of the Dialog
class. The FileDialog class uses the operating system's
native dialog boxes to query the user for the name of a file to
be loaded or saved. The getDirectory() and getFile()
methods return the file's directory and filename. The setDirectory()
and setFile() methods are used to set the state of the
dialog box to a particular directory and file when it is initially
opened. The getMode() method returns the LOAD
or SAVE mode of the dialog box. The setFileNameFilter()
and getFileNameFilter() methods are used to associate
an object of the FileNameFilter interface with the dialog
box. No classes that implement this interface are currently provided
by the Java API. The TextEdit example in Chapter 18
illustrates the use of the FileDialog class in performing
file load and save operations.
This chapter shows you how to use the Menu, Button,
and Dialog classes. It describes the available menu and
button options and shows you how to quickly and easily construct
menus and buttons for your window programs using the MyMenu,
MyMenuBar, and ButtonBar classes. The use of
dialog boxes is also covered. You have created the MessageDialog
class, which you can reuse in other programs. Chapter 21,
"Checkboxes, Choices, and Lists," shows you how to work
with those elements.

Contact
reference@developer.com with questions or comments.
Copyright 1998
EarthWeb Inc., All rights reserved.
PLEASE READ THE ACCEPTABLE USAGE STATEMENT.
Copyright 1998 Macmillan Computer Publishing. All rights reserved.