All Categories :
Java
Chapter 22
Working with Dialog Boxes
by K. C. Hopson
CONTENTS
This chapter focuses on the Dialog
class, which is the basis for writing dialog boxes in Java. The
class is illustrated through several dialog box examples which
provide tips about how to use some of the more obscure features
of the Abstract Windowing Toolkit (AWT). The FileDialog
class is discussed at the end of this chapter.
To get a proper understanding of the Dialog
class, however, it is important to review how the Window
and Frame classes work.
This chapter begins with a quick review of these two classes.
The Window class is used
in AWT to create popup windows that appear outside the constraints
of the normal browser area allocated to an applet. Because the
Window class is derived from
the Container class, it can
contain other components. Unlike applet components tied directly
to a browser page, Window
classes are not restricted to a prespecified area of the screen.
Window objects can be resized
as their immediate requirements dictate. AWT can perform this
automatically through the Window
class's pack() method; this
method works with the Window
layout (by default, BorderLayout)
to arrive at the optimal presentation of the window given its
contained components and screen resolution. Typically, pack()
is called before a window is displayed. Windows are not made visible
until the show() method is
called. Windows are removed from the screen and their resources
are freed when the dispose()
method is invoked.
The Frame class extends the
Window class by adding a
title bar, a border for resizing, support for menus, and the ability
to modify the system cursor to various states such as waiting
or moving. For most GUI platforms, the frame's title bar is tied
to system control boxes, such as minimize, maximize, or destroy.
Consequently, the Frame class
has all the elements necessary to make an applet look like a "real"
application, complete with menus and system controls.
Figure 22.1 and Listing 22.1 present a simple Frame
applet that changes the cursor to a state based on the button
selected.
Figure 22.1: A Frame applet that changes the state of the cursor.
Listing 22.1. Code for the Frame
class that changes the cursor state.
import java.awt.*;
import java.lang.*;
import java.applet.*;
// This applet simply starts up the frame used to
// show different frame cursors...
public class FrameCursorApplet extends Applet {
public void init() {
// Create the frame with a title...
new FrameCursor("Frame Cursors");
}
}
// The frame for letting the user pick different
// cursors to display...
class FrameCursor extends Frame {
// Create the frame with a title...
public FrameCursor(String title) {
// Call the superclass constructor...
super(title);
// Create a grid layout to place the buttons...
setLayout(new GridLayout(3,2));
// Add the buttons for choosing the cursor...
add(new Button("Default"));
add(new Button("Wait"));
add(new Button("Hand"));
add(new Button("Move"));
add(new Button("Text"));
add(new Button("SE Resize"));
// Pack and display...
pack();
resize(300,200); // Make it a reasonable size...
show();
}
// Handle events...
public boolean handleEvent(Event e) {
switch(e.id) {
case e.WINDOW_DESTROY:
dispose(); // Erase frame
return true;
case Event.ACTION_EVENT:
if (e.target instanceof Button)
SetCursor((Button)e.target);
return true;
default:
return false;
}
}
// Set the cursor based on the button chosen...
void SetCursor(Button btn) {
// Get the label of the button...
String selection = btn.getLabel();
//Set the cursor based on that label...
if (selection.equals("Wait"))
setCursor(Frame.WAIT_CURSOR);
else if (selection.equals("Hand"))
setCursor(Frame.HAND_CURSOR);
else if (selection.equals("Move"))
setCursor(Frame.MOVE_CURSOR);
else if (selection.equals("Text"))
setCursor(Frame.TEXT_CURSOR);
else if (selection.equals("SE Resize"))
setCursor(Frame.SE_RESIZE_CURSOR);
else // Just use the default...
setCursor(Frame.DEFAULT_CURSOR);
}
}
The applet class, FrameCursorApplet,
does little more than launch the main frame, FrameCursor.
The constructor for this frame begins by calling the frame superconstructor.
The sole parameter is the caption displayed on the title bar.
The layout for the frame is then set: Although the default is
BorderLayout, in this case
you want a 3-by-2 grid matrix, hence the use of GridLayout.
Next, the buttons are added to the frame, with names representing
the cursor state to be selected. After all the components have
been added, the pack() method
is invoked so that the button placement can be optimized. Because
this optimized placement results in a small frame (six buttons
sized tightly around the label text doesn't take much space),
the resize() method is called
to make the frame larger. Finally, the frame is displayed with
the show() method.
When a button is selected, the custom method setCursor()
is invoked. This method takes the button label and figures out
which cursor should be displayed. The Frame
class's setCursor() method
is used to set the cursor state; its parameter is a static integer
defined as part of the Frame
class.
The current state of the cursor can be retrieved with the getCursorType()
method. The getTitle() and
setTitle() frame methods
can be used to get and set the title bar caption. Similarly, the
getIconImage() and setIconImage()
methods can be used to get and set the image display of an iconized
frame.
Introduction to the Dialog Class
Like the Frame class, the
Dialog class is a subclass
of the Window class. Dialog
boxes differ from frames in a couple of subtle ways, however.
The most important of these differences is that dialog boxes can
be modal. When a modal dialog box is displayed, input to
other windows in the applet is blocked until the dialog box is
disposed. This feature highlights the general purpose of dialog
boxes, which is to give the user a warning or a decision to be
made before the program can continue. Although support for nonmodal,
or modeless, dialog boxes is supported, most dialog boxes
are modal.
There are two constructors for the Dialog
class. Both take a Frame
object as a parameter; they also take a boolean
flag that indicates whether the dialog box should be modal. If
the flag is set to true,
the dialog box is modal. The constructors differ only in a parameter
that specifies whether the dialog box should have a title caption.
It is this constructor that is used in the example that follows.
Figure 22.2 shows a variation of the applet introduced in the
preceding section, except that a dialog box is used to change
the cursor state. Listing 22.2 shows the code for the Dialog
class, called ChangeCursorDialog.
Note how similar the dialog box here is to the frame in Figure
22.1.
Figure 22.2: Using a dialog box to change the state of the cursor.
Listing 22.2. Code for the Dialog
class that changes the cursor state.
import java.awt.*;
import java.lang.*;
import java.applet.*;
// Dialog that presents a grid of buttons
// for choosing the Frame cursor. A Cancel
// button exits the dialog...
class ChangeCursorDialog extends Dialog {
FrameMenuCursor fr;
// Create the dialog and store the title string...
public ChangeCursorDialog(Frame parent,boolean modal,String title) {
// Create dialog with title
super(parent,title,modal);
fr = (FrameMenuCursor)parent;
// The layout is Grid layout...
setLayout(new GridLayout(3,2));
// Add the button options
add(new Button("Default"));
add(new Button("Wait"));
add(new Button("Hand"));
add(new Button("Move"));
add(new Button("Text"));
add(new Button("Cancel"));
// Pack and size for display...
pack();
resize(300,200);
}
// Look for button selections to
// change the cursor...
public boolean action(Event e,Object arg) {
// If button was selected then exit dialog..
if (e.target instanceof Button) {
// And possibly change the cursor...
if (arg.equals("Default"))
fr.setCursor(Frame.DEFAULT_CURSOR);
if (arg.equals("Wait"))
fr.setCursor(Frame.WAIT_CURSOR);
if (arg.equals("Hand"))
fr.setCursor(Frame.HAND_CURSOR);
if (arg.equals("Move"))
fr.setCursor(Frame.MOVE_CURSOR);
if (arg.equals("Text"))
fr.setCursor(Frame.TEXT_CURSOR);
dispose();
}
return false;
}
}
You can declare the dialog box and instantiate it as follows:
ChangeCursorDialog dlg;
dlg = new ChangeCursorDialog(this,true,"Change the cursor");
When it is time to display the dialog box, you can declare this
method:
dlg.show(); // Make the dialog visible...
In this section, a color dialog box is created to further explain
how to use the Dialog class.
The example lets you associate a color with the foreground and
background states of text. Fig-ure 22.3 shows how the dialog box
appears in a browser.
Figure 22.3: The color dialog box.
How the Color Dialog Box Is Used
When the dialog box appears, a list control at the top left of
the dialog box shows which elements of the text can be modified.
These colors are normal foreground, normal background, highlighted
foreground, and highlighted background. When you select a list
item, the radio button for the corresponding color is highlighted.
A text display underneath the list shows what the text would look
like with the given colors. The text display shows either the
normal state (with both foreground and background colors) or the
background state. If you select a new color with the radio buttons,
the Canvas object is updated
to show what the new foreground and background combination would
look like. The text can be updated with the color settings for
the current list item when you select the Update button.
The Construction of the Color Dialog Box
Four classes are used to construct the color dialog box. The ChooseColorDialog
class is a subclass of Dialog
and controls the main display and control of the dialog box. The
colorDisplay class is a Canvas
class derivative that draws text with colors corresponding to
the selected foreground and background display. The ColoredCheckbox
class draws a checkbox associated with a certain Color
object; the background of the box is drawn according to that color.
The ColoredCheckboxGroup
class groups ColoredCheckbox
items together so that they can function as part of a radio button
group.
The discussion of the color dialog box begins with its underlying
components. Listing 22.3 shows the code for the ColoredCheckbox
class. Its most interesting feature is that it associates itself
with a given Color object.
It paints its background according to the Color
object and, through the setIfColorMatches()
method, turns its checkbox on if the color sent to it matches
its internal color. The checkbox in this case is a radio button
because the class is associated with a CheckboxGroup
object. Checkbox objects have radio buttons only if they are associated
with a CheckboxGroup object;
only one radio button in a checkbox group can be selected at a
time. If no checkbox group is specified for a checkbox object,
there are no restrictions on which boxes can be selected.
Listing 22.3. The ColoredCheckbox
class.
// Class for creating a checkbox associated
// with a given color...
class ColoredCheckbox extends Checkbox {
Color color; // The color of this checkbox...
// Constructor creates checkbox with specified color...
public ColoredCheckbox(Color color, String label,
CheckboxGroup grp, boolean set) {
// Call the default constructor...
super(label,grp,set);
this.color = color;
setBackground(color);
}
// Sets itself to true if it matches the color
public void setIfColorMatches(Color match) {
if (color == match)
setState(true);
else
setState(false);
}
// Return the color matching this box...
public Color getColor() {
return color;
}
}
The ColoredCheckboxGroup
is used to contain ColoredCheckbox
objects. Its constructor creates a preselected number of colored
checkboxes to be associated with a Panel
object. Here are the first few lines of the ColoredCheckboxGroup
class declaration:
class ColoredCheckboxGroup extends CheckboxGroup {
// Array to hold checkboxes...
ColoredCheckbox c[] = new ColoredCheckbox[12];
// Constructor. Create the checkboxes with
// no default color chosen...
public ColoredCheckboxGroup(Panel p) {
// Call the default constructor...
super();
// Create the checkboxes and store in panel and reference array...
c[0] = new ColoredCheckbox(Color.black,"Black",this,false);
p.add(c[0]);
c[1] = new ColoredCheckbox(Color.cyan,"Cyan",this,false);
p.add(c[1]);
Strangely enough, ColoredCheckboxGroup
is not a Container object.
Consequently, the checkboxes must be associated with a Panel
object to meet the needs at hand. Note the use of the Color
constants in constructing the ColoredCheckbox
objects. The reference array (variable c)
is used in the other method of the class, setMatchingColor(),
which is used to set the radio button of the ColoredCheckbox
object that matches a certain color:
public void setMatchingColor(Color match) {
for (int i = 0; i < c.length; ++i)
c[i].setIfColorMatches(match);
}
Because ColoredCheckbox objects
are self-identifying by color, this technique prevents a long
and cumbersome walk through hard-coded color names to see which
radio button should be turned on.
The colorDisplay class is
a Canvas derivative that
draws text (specified in the displayText
String variable) with a specified
foreground and background color. Listing 22.4 highlights some
of the more interesting features of the class.
Listing 22.4. Portions of the colorDisplay
class.
// The layout will call this to get the minimum size
// of the object. In this case, you want it to be at
// least big enough to fit the display text...
public Dimension minimumSize() {
// Get the metrics of the current font...
FontMetrics fm = getFontMetrics(getFont());
return new Dimension(fm.stringWidth(displayText),
2 * fm.getHeight());
}
// Paint the colors and text...
public synchronized void paint(Graphics g) {
if ((foreground == null) || (background == null))
return;
// Set background...
Dimension dm = size();
g.setColor(background);
g.fillRect(0,0,dm.width,dm.height);
// Draw the string
g.setColor(foreground);
// Set dimensions. Move just from left...
FontMetrics fm = getFontMetrics(getFont());
int x = fm.charWidth('W');
// And center in height...
int y = fm.getHeight();
g.drawString(displayText,x,y);
}
The paint() method draws
the canvas if a background and foreground color have been selected.
The method starts by getting the size of its drawing area through
the size() method; this method
is a standard part of subclasses of Component.
It then fills in the background color through the setColor()
and fillRect() methods of
the Graphics class. The paint()
method then sets the color of the text to be displayed (the foreground).
By getting the current FontMetrics,
the canvas can figure out a good location for the text string;
the getHeight() method returns
the total height of the font. The drawString()
method then draws the text at the specified location.
The minimumSize() method
is used with layouts, which are discussed in Chapter 21,
"Creating User Interface Components." When AWT constructs
the display of a group of components, it works with the layouts
to decide what position and size a component should have. Sometimes,
you may want a component to exercise some input into what its
size will be. You can invoke two methods of the Component
class to do this. The preferredSize()
method returns the dimensions of the preferred size of the component.
The minimumSize() method
returns the smallest size in which the component should be made.
For the colorDisplay() class,
the minimumSize() method
returns that the component should be wide enough to display the
text string and twice as high as its current font. The method
does this by getting the FontMetrics
information of the current font and calling the stringWidth()
and getHeight() methods respectively.
Finally, the dialog box is ready to be constructed. Listing 22.5
highlights the declarations and methods used to construct the
color dialog box.
Listing 22.5. The construction of the ChooseColorDialog
class.
// Dialog box for choosing display colors...
public class ChooseColorDialog extends Dialog {
Frame fr; // What to update...
ColoredCheckboxGroup colorGrp; // To hold radio buttons of colors...
List choiceList; // List of color choices...
colorDisplay d; // This is the text display...
// Defines for listbox values...
static int NORMAL_FORE = 0;
static int NORMAL_BACK = 1;
static int HILITE_FORE = 2;
static int HILITE_BACK = 3;
// Construct dialog to allow color to be chosen...
public ChooseColorDialog(Frame parent,boolean modal) {
// Create dialog with title
super(parent,"Color Dialog",modal);
fr = parent;
// Create the dialog components...
createComponents();
pack(); // Compact...
// Resize to fit everything...
resize(preferredSize());
}
// The layout will call this to get the preferred size
// of the dialog. Make it big enough for the listbox text
// the checkboxes, canvas, and buttons...
public Dimension preferredSize() {
// Get the metrics of the current font...
FontMetrics fm = getFontMetrics(getFont());
int width = 3 * fm.stringWidth("Highlighted foreground");
int height = 24 * fm.getHeight();
return new Dimension(width,height);
}
// Create the main display panel...
void createComponents() {
// Use gridbag constraints...
GridBagLayout g = new GridBagLayout();
setLayout(g);
GridBagConstraints gbc = new GridBagConstraints();
// Set the constraints for the top objects...
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridheight = 10;
// Add the listbox of choices...
choiceList = new List();
choiceList.addItem("Normal foreground");
choiceList.addItem("Normal background");
choiceList.addItem("Highlighted foreground");
choiceList.addItem("Highlighted background");
g.setConstraints(choiceList,gbc);
add(choiceList);
// Create the checkbox panel
Panel checkboxPanel = new Panel();
checkboxPanel.setLayout(new GridLayout(12,1));
// Create the checkbox group and add radio buttons...
colorGrp = new ColoredCheckboxGroup(checkboxPanel);
colorGrp.setMatchingColor(Color.magenta);
// Create checkbox panel to right...
gbc.gridwidth = GridBagConstraints.REMAINDER;
g.setConstraints(checkboxPanel,gbc);
add(checkboxPanel);
// Display the color chosen...
d = new colorDisplay("This is how the text looks.");
// Add to grid bag...
gbc.weighty = 0.0;
gbc.weightx = 1.0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.gridheight = 1;
g.setConstraints(d,gbc);
add(d);
// Two buttons: "Update" and "Cancel"
Panel p = new Panel();
p.add(new Button("Update"));
p.add(new Button("Cancel"));
// Add to grid bag...
gbc.gridwidth = GridBagConstraints.REMAINDER;
g.setConstraints(p,gbc);
add(p);
}
The createComponents() method
adds the components to the dialog box by using the complex GridBagLayout
class. The main thing to be done here is to have most of the space
that is taken up by the list control set to half the dialog box
size; the color checkboxes take up the other half (refer back
to Figure 22.3). The key reason for doing this is to set the GridBagConstraint's
weighty and gridheight
variables to the appropriate values. By setting the former to
1.0, you tell the layout
that the associated components should be given preeminence in
terms of the layout's height. When weighty
is set to 0.0, the height
of the corresponding components is given lower priority.
The preferredSize() method
in Listing 22.5 returns the desired dimensions of the dialog box.
It should be 3 times as wide as the longest string in the list
component, and 24 times as high as the current font. With these
settings, everything should fit comfortably in the dialog box.
Using the Dialog Box
Once the dialog box is displayed, its event loop is entered. Listing
22.6 details the dialog box's handleEvent()
method. This code has several subtleties worth noting. Most of
the work is performed when an action occurs, as indicated by the
ACTION_EVENT method. When
a button is selected, the argument of the Event
object is set to the name of the button. The handleEvent()
method looks at this name to decide what to do. If the name is
Cancel, the dialog box is
removed from the screen with the dispose()
method, and control returns to the calling frame. You can use
the Update button to set the colors according to what is currently
highlighted.
Listing 22.6. The handleEvent()
method of the ChooseColorDialog
class.
// Wait for Cancel or OK buttons to be chosen...
public boolean handleEvent(Event e) {
switch(e.id) {
case Event.ACTION_EVENT:
// Kill the dialog...
if (e.arg.equals("Cancel")) {
dispose(); // Remove Dialog...
return true;
} // end if
// Update colors...
if (e.arg.equals("Update")) {
// INSERT YOUR CODE HERE!
return true;
} // end if
if (e.target instanceof Checkbox) {
selectedRadioItem();
return false;
}
return false;
// User selected a listbox item...
case Event.LIST_SELECT:
// Set up caption colors and color choice highlight...
if (e.target instanceof List) {
selectedChoiceListItem();
return false;
} // end list if
return false;
default:
return false;
} // end switch
}
If the target of the ACTION_EVENT
is a checkbox, a radio button is selected and the selectedRadioItems()
method is called. This method sets the colorDisplay
object's foreground or background colors according to the radio
button chosen and the current selection in the list.
If you click a list item, a LIST_SELECT
event is issued. In this case, the selectedChoiceListItems()
method is invoked. This method sets the colorDisplay
object's settings according to the current list selection; this
process must take into account both the foreground and background
colors. The ColoredCheckboxGroup's
setMatchingColor() method
is called to set the radio button of the ColoredCheckbox
object corresponding to the current list color.
Calling the Dialog Box
The Frame object is responsible
for bringing up the color dialog box. It can declare a variable
of the colorDialog class
as follows:
ChooseColorDialog colorDialog; // Color Dialog...
In its constructor, the frame instantiates the color dialog box
with the following call:
colorDialog = new ChooseColorDialog(this, true);
This code fragment states that the frame is the parent of the
dialog box and its appearance is modal. Recall that a modal dialog
box does not allow input to other windows while it is being displayed.
A dialog box does not automatically appear when it is constructed;
to make the dialog box, you must specifically call the show()
method. The color dialog box overrides the show()
method so that it can do some setup before the dialog box appears:
public synchronized void show() {
super.show(); // Call the default show method...
// Set the listbox default...
choiceList.select(0);
// Set up caption colors and color choice highlight...
selectedChoiceListItem();
}
The last method called, selectedChoiceListItem(),
sets the radio buttons and display canvas to values corresponding
to the current list selection.
This discussion of the font dialog box example will not be as
lengthy as the preceding overview of the color dialog box. In
many ways, the two examples are similar, so a detailed explanation
of the font dialog box isn't required.
Figure 22.4 shows the font dialog box. It is based on the ChooseFontDialog
class, which displays its components in a two-column style similar
to the color dialog box. The current font family, style, and size
are shown in a Canvas display
object of the fontDisplay
class. This class is very similar to the colorDisplay
class.
Figure 22.4: The font dialog box.
The list component on the left side of the dialog box shows the
fonts available on the current platform. It uses the AWT Toolkit
class to get this information. Here is the code that creates the
control and adds the font families:
// Add the listbox of choices...
// Get the selection from the toolkit...
choiceList = new List();
String fontList[] = Toolkit.getDefaultToolkit().getFontList();
for (int i = 0; i < fontList.length; ++i)
choiceList.addItem(fontList[i]);
A choice box is added to the dialog box to enumerate font sizes
that can be used. Two checkboxes are used to set the bold and
italicized styles. If none of these are set, the font's style
is set to plain.
Every time one of these controls is changed, the font display
is updated with a new font. This happens in the paintSample()
method. Listing 22.7 shows the code for the paintSample()
method and also features the full source code of the font dialog
box.
Listing 22.7. The full source code of the font dialog box.
// Dialog box for choosing display colors...
public class ChooseFontDialog extends Dialog {
Frame fr; // What to update...
List choiceList; // List of color choices...
fontDisplay d; // This is the text display...
Choice choiceSize; // Size of font...
Checkbox checkItalics;
Checkbox checkBold;
Font currentFont; // Current font in sample...
Font defaultFont; // Store font dialog was created with...
// Construct dialog to allow color to be chosen...
public ChooseFontDialog(Frame parent,boolean modal) {
// Create dialog with title
super(parent,"Font Dialog",modal);
fr = parent;
defaultFont = getFont();
// Create the dialog components...
createComponents();
}
// Get the default font and set up display...
private void setDefaultFont() {
// SET YOUR DEFAULT FONT HERE!
currentFont = getFont();
// Get default list...
String s = currentFont.getName();
int index = findListString(choiceList,s);
if (index >= 0)
choiceList.select(index);
else
choiceList.select(0);
// Get default size
int sizeFont = currentFont.getSize();
index = findChoiceString(choiceSize,
String.valueOf(sizeFont));
if (index >= 0)
choiceSize.select(index);
else
choiceSize.select(0);
// Set the style displays...
int styleFont = currentFont.getStyle();
if ((styleFont & Font.BOLD) != 0)
checkBold.setState(true);
else
checkBold.setState(false);
if ((styleFont & Font.ITALIC) != 0)
checkItalics.setState(true);
else
checkItalics.setState(false);
// Set the canvas style...
d.setFont(currentFont);
}
// Wait for Cancel or OK buttons to be chosen...
public boolean handleEvent(Event e) {
switch(e.id) {
case Event.ACTION_EVENT:
// Kill the dialog...
if (e.arg.equals("Cancel")) {
dispose(); // Remove Dialog...
return true;
} // end if
// Update colors on the text
if (e.arg.equals("OK")) {
// YOUR UPDATE CODE GOES HERE!
dispose();
return true;
} // end if
if (e.target instanceof Choice) {
paintSample();
return false;
} // end list if
if (e.target instanceof Checkbox) {
paintSample();
return false;
} // end list if
return false;
// User selected a listbox item...
case Event.LIST_SELECT:
// Set up caption colors and color choice highlight...
if (e.target instanceof List) {
paintSample();
return false;
} // end list if
return false;
default:
return false;
} // end switch
}
// The layout will call this to get the preferred size
// of the dialog. Make it big enough for the components
public Dimension preferredSize() {
// Get the metrics of the current font...
FontMetrics fm = getFontMetrics(getFont());
int width = 3 * fm.stringWidth("Highlighted foreground");
int height = 14 * fm.getHeight();
return new Dimension(width,height);
}
// Create the main display panel...
private void createComponents() {
// Use gridbag constraints...
GridBagLayout g = new GridBagLayout();
setLayout(g);
GridBagConstraints gbc = new GridBagConstraints();
// Set the constraints for the top objects...
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridheight = 10;
// Add the listbox of choices...
// Get the selection from the toolkit...
choiceList = new List();
String fontList[] = Toolkit.getDefaultToolkit().getFontList();
for (int i = 0; i < fontList.length; ++i)
choiceList.addItem(fontList[i]);
g.setConstraints(choiceList,gbc);
add(choiceList);
// Set the default values...
gbc.weighty = 0.0;
gbc.weightx = 1.0;
gbc.gridheight = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
// Create a label for display...
Label l = new Label("Size:");
// Add to grid bag...
g.setConstraints(l,gbc);
add(l);
// Create the choice box...
choiceSize = new Choice();
choiceSize.addItem("8");
choiceSize.addItem("10");
choiceSize.addItem("12");
choiceSize.addItem("14");
choiceSize.addItem("16");
choiceSize.addItem("20");
// Add to grid bag...
g.setConstraints(choiceSize,gbc);
add(choiceSize);
// Add Italics...
checkItalics = new Checkbox("Italics");
g.setConstraints(checkItalics,gbc);
add(checkItalics);
// Add Bold...
checkBold = new Checkbox("Bold");
g.setConstraints(checkBold,gbc);
add(checkBold);
// Display the color chosen...
d = new fontDisplay("Sample Text");
// Add to grid bag...
g.setConstraints(d,gbc);
add(d);
// Two buttons: "OK" and "Cancel"
Panel p = new Panel();
p.add(new Button("OK"));
p.add(new Button("Cancel"));
// Add to grid bag...
gbc.gridwidth = GridBagConstraints.REMAINDER;
g.setConstraints(p,gbc);
add(p);
}
// Setup defaults upon showing...
public synchronized void show() {
super.show(); // Call the default constructor...
// Set the font dialog started off with...
setFont(defaultFont);
// Set up defaults...
setDefaultFont();
pack(); // Compact...
// Resize to fit everything...
resize(preferredSize());
}
// Set the display canvas to show itself with
// the currently selected font
private synchronized void paintSample() {
// Get the family to display
String fontName = choiceList.getSelectedItem();
// Get its point size
String fontSize = choiceSize.getSelectedItem();
// Set its style
int fontStyle = Font.PLAIN;
if (checkItalics.getState())
fontStyle += Font.ITALIC;
if (checkBold.getState())
fontStyle += Font.BOLD;
// Create a font with the proper attributes...
currentFont = new Font(fontName,fontStyle,
Integer.parseInt(fontSize));
// Set the new font on the canvas...
d.setFont(currentFont);
// Repaint it so the new font is displayed..
d.repaint();
}
// Return index of string in list...
// -1 means not found
public int findListString(List l,String s) {
for (int i = 0; i < l.countItems(); ++i) {
if (s.equals(l.getItem(i)) )
return i;
}
return -1;
}
// Return index of string in choice...
// -1 means not found
public int findChoiceString(Choice c,String s) {
for (int i = 0; i < c.countItems(); ++i) {
if (s.equals(c.getItem(i)) )
return i;
}
return -1;
}
}
// A small class that illustrates the
// current highlight and background
class fontDisplay extends Canvas {
String displayText;
// Construct the display by storing the
// text to be displayed...
public fontDisplay(String displayText) {
super();
this.displayText = displayText;
}
// The layout will call this to get the minimum size
// of the object. In this case we want it to be at
// least big enough to fit the display test...
public Dimension minimumSize() {
// Get the metrics of the current font...
FontMetrics fm = getFontMetrics(getFont());
return new Dimension(fm.stringWidth(displayText),
4 * fm.getHeight());
}
// Paint the colors and text...
public synchronized void paint(Graphics g) {
// Set background...
Dimension dm = size();
g.setColor(Color.white);
g.fillRect(0,0,dm.width,dm.height);
// Draw the string
g.setColor(Color.black);
// Set dimensions. Move just from left...
FontMetrics fm = getFontMetrics(getFont());
int x = fm.charWidth('I');
// And center in height...
int y = fm.getHeight();
g.drawString(displayText,x,y);
}
}
The FileDialog Class
The FileDialog class is a
subclass of Dialog used to
provide a platform-independent approach to letting the user select
the files to be loaded or saved. Instances of the FileDialog
class usually mirror the underlying GUI conventions. For example,
a FontDialog object for loading
a file on the Windows 95 environment follows the Windows 95 Open
dialog box conventions.
The FileDialog can be constructed
to be in a mode to load a file or save a file. These dialog boxes
look similar but perform slightly differently. For example, the
Save version of the dialog box notifies the user that a file exists
if a filename is given for a preexisting file. Here's the code
you need to construct dialog boxes for both the load and save
cases:
FileDialog openFileDialog; // File Open Dialog...
FileDialog saveFileDialog; // File Save Dialog...
openFileDialog = new FileDialog(this,"Open File",
FileDialog.LOAD);
saveFileDialog = new FileDialog(this,"Save File",
FileDialog.SAVE);
The integer flag in the last parameter of the constructors indicates
the mode in which the dialog box should function.
When the dialog box is displayed with the show()
method, it acts in a modal fashion so that input to the frame
is blocked while it is displayed. After a choice has been made,
the chosen file and directory can be retrieved with the getFile()
and getDirectory() methods.
The former returns a null
value if the user cancels out of the dialog box.
It is interesting to note that the FileDialog
objects constructed here do not appear when the applet is run
in Netscape Navigator. For security reasons, Netscape does not
allow any file-based methods to be invoked from an applet. In
the latest incarnation of Microsoft Internet Explorer, you actually
get a security exception if you even attempt to reference the
FileDialog class! Consequently,
the FileDialog class is really
useful only for standalone applications.
As the examples in this have shown, most of the work in creating a dialog box is setting
up the component controls. The techniques for doing this are very
similar to creating controls in an applet, with the difference
that you may have to call pack()
or the preferredSize() method
to get the exact appearance you are after.
The other big issue with dialog boxes is related to security.
Some browsers, like Netscape Navigator, consider dialog boxes
to be a possible security threat. For this reason, a warning or
an "untrusted window" message may appear in the browser
status bar. In the worst case, the dialog box may not even appear
or may be flagged with a security exception! As stated before,
this is the case with the FileDialog
class in Microsoft's Internet Explorer. For these reasons, dialog
boxes must be used with great caution in applets. When all is
said and done, dialog boxes may be best suited for standalone
Java applications.
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.