All Categories :
Java
Chapter 22
Text and Fonts
CONTENTS
This chapter covers the details of Java's text- and font-related
classes. It shows how to use the TextComponent
subclasses and how to display text with the canvas. It explains
Java's use of fonts and shows how the Font
and FontMetrics classes are
used to provide custom control of text display. When you finish
this chapter, you will be able to effectively use text and fonts
in your Java window programs.
The Text
Classes
You are now fairly familiar with the text-related classes supported
by Java because you've used TextArea
and TextField objects in
the examples presented so far. Let's review these classes and
then you can learn how to use font-related classes to alter the
way text is presented to the user.
The TextComponent class is
the superclass of the TextField
and TextArea classes. It
extends the Component class
to support text-related processing. TextComponent
provides several methods that are used to process text that is
selected by the user. The setEditable()
method determines whether a TextComponent
object is read-only or can be edited. The getText()
and setText() methods are
its most popular methods and are used with all text-related classes.
The TextField class implements
a simple, one-line text field. The visible length of the field
(in characters) can be specified. Character echoing can be disabled
to implement password-like text fields.
The TextArea class implements
a multiple-line text field and supports a number of methods for
updating the field by inserting, appending, and replacing text.
The number of rows and columns associated with a text field can
be specified.
Font Basics
The Font class provides a
platform-independent method of specifying and using fonts. The
Font class constructor constructs
Font objects using the font's
name, style (PLAIN, BOLD,
ITALIC, or BOLD
+ ITALIC), and point size. Java's fonts are named
in a platform-independent manner and then mapped to local fonts
that are supported by the operating system on which it executes.
The getName() method returns
the logical Java font name of a particular font and the getFamily()
method returns the operating system-specific name of the font.
The standard Java font names are Dialog, DialogInput, Courier,
Helvetica, TimesRoman, and ZapfDingbats. You'll see examples of
these fonts shortly.
The FontMetrics class is
used to return the specific parameters for a particular Font
object. An object of this class is created using the getFontMetrics()
methods supported by the Component
class and other classes, such as the Graphics
and Toolkit classes. The
FontMetrics access methods
provide access to the details of the implementation of a Font
object.
The bytesWidth(), charWidth(),
charsWidth(), getWidths(),
and stringWidth() methods
are used to determine the width of a text object in pixels. These
methods are essential for determining the horizontal position
of text on the screen.
When text characters are displayed, they are displayed relative
to a baseline. The baseline is the line drawn through the
bottom of non-descending characters. For example, if you drew
a line at the bottom of most text displayed on this line, you
would get the text's baseline. Some characters, such as g
and y, descend below the baseline. The number of pixels
that the characters of a font descend below the baseline are known
as the font's descent. The number of pixels that the characters
of a font extend above the baseline are known as the font's ascent.
In addition to a font's ascent and descent, a third parameter,
referred to as the font's leading, is used to describe
the amount of vertical spacing, in pixels, used between the descent
of a line of text and the ascent of the line of text below it.
The overall height of a font is the sum of its leading, ascent,
and spacing and is equal to the distance between baselines (in
pixels) of vertically adjacent lines of text. The getLeading(),
getAscent(), getDescent(),
and getHeight() methods of
the FontMetrics class are
used to access these important font-related parameters.
The getMaxAdvance(), getMaxAscent(),
and getMaxDescent() methods
are provided for backward compatibility with earlier Java versions.
The Toolkit class provides
a link between the platform-independent Java implementation and
its platform-specific characteristics. Among the many uninteresting
methods implemented by this class are the getFontList(),
getFontMetrics(), getScreenSize(),
and getScreenResolution()
methods. The getFontList()
method returns a list of fonts that are accessible from Java.
The getFontMetrics() method
identifies the font metrics for a particular font. The getScreenSize()
method identifies the screen dimension in terms of horizontal
and vertical dots. The getScreenResolution()
method identifies the screen resolution in dots per inch.
getFontList() is the method
of interest for this chapter. You'll use it to get a list of the
fonts available to Java in the next section.
The FontApp program illustrates
the use of the Font, FontMetrics,
and Toolkit classes and shows
how to draw text on a Graphics
object. Its source code is shown in Listing 22.1.
Listing 22.1. The source code of the FontApp
program.
import java.awt.*;
import jdg.ch20.*;
public class FontApp extends Frame {
MyMenuBar menuBar;
Toolkit toolkit;
Font defaultFont;
String fontNames[];
int screenWidth = 400;
int screenHeight = 400;
public static void main(String args[]){
FontApp app = new FontApp();
}
public FontApp() {
super("FontApp");
setup();
pack();
resize(screenWidth,screenHeight);
show();
}
void setup() {
setBackground(Color.white);
setupMenuBar();
setMenuBar(menuBar);
setupFonts();
}
void setupMenuBar() {
String menuItems[][] = {{"File","Exit"}};
menuBar = new MyMenuBar(menuItems);
}
void setupFonts() {
toolkit = getToolkit();
defaultFont = getFont();
fontNames = toolkit.getFontList();
}
public void paint(Graphics g) {
int styles[] = {Font.PLAIN,Font.BOLD,Font.ITALIC,Font.BOLD+Font.ITALIC};
String styleNames[] = {"Plain","Bold","Italic","Bold
and Italic"};
int y = 0;
int size = 14;
for(int i=0;i<fontNames.length;++i) {
for(int j=0;j<styles.length;++j) {
Font newFont = new Font(fontNames[i],styles[j],size);
FontMetrics fm = g.getFontMetrics(newFont);
g.setFont(newFont);
String text = fontNames[i]+"-"+styleNames[j];
int x = (screenWidth - fm.stringWidth(text))/2;
g.drawString(text,x,y+fm.getLeading()+fm.getAscent());
y += fm.getHeight();
}
}
}
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;
}
}
}
return false;
}
}
The FontApp program does
not provide much functionality. Just run it and it will display
a list of the fonts that are currently available to Java, with
each name written in its font. Figure 22.1
shows its display. The program's importance is not what it does,
but in how it does it. By closely examining this program, you'll
be able to quickly come up to speed on working with Java fonts.
Figure 22.1 : The FontApp opening window.
The FontApp class declares
a number of field variables. The toolkit
variable is used to refer to the Toolkit
object associated with the program window. The defaultFont
variable identifies the default font used by the program. The
fontNames[] array is used
to store the names of the fonts that are accessible to Java.
The setupFonts() method obtains
the Toolkit object associated
with the program's window using the getToolkit()
method and assigns this object to the toolkit
variable. The current font used by the program is accessed by
getFont() and assigned to
the defaultFont variable.
The Toolkit object is then
used to obtain the current list of font names via the getFontList()
method of the Toolkit class.
That's all for the program's setup. The program's event handling
is the standard Exit menu item and WINDOW_DESTROY
event processing.
The paint() method is where
the primary processing of interest takes place. The styles[]
and styleNames[] arrays are
used to identify the various text styles and their associated
string descriptions. The y
variable identifies the vertical screen position where text is
displayed. The size variable
identifies the point size used to display a font.
The paint() method uses two
for statements. The outer
statement iterates through the list of font names, and the inner
statement iterates through the font styles. At each passes through
the inner loop, a new font is created with the specified name,
style, and size. The getFontMetrics()
method of the Graphics class
is used to obtain the FontMetrics
object associated with the newly created font and this object
is assigned to the fm variable.
The setFont() method of the
Graphics class is used to
set the current font to the new font.
The next line of text to be displayed is created by concatenating
the font name and its style name. The horizontal position at which
the text is to be displayed in order for it to be centered is
calculated based on the width of the text (in pixels) returned
by the stringWidth() method
of the FontMetrics class
and the initial width of the program window. The vertical position
where the text is to be displayed is its baseline and is determined
by adding the leading and ascent values of the font with the y
variable. These values are obtained using the getLeading()
and getAscent() methods of
the current FontMetric object.
The y variable identifies
the point of maximum descent of the previously displayed line
of text. It is then updated for the current line of text by adding
the height of the current font returned by the getHeight()
method of the FontMetric
class.
WYSIWYG
Editors
The Font and FontMetrics
classes are not confined to text that is drawn on Graphics
objects. These classes can also be used with the TextField
and TextArea classes. These
classes automatically calculate the correct text-display locations
using the native text objects supported by the local operating-system
platform. In addition to changing text fonts, the TextField
and TextArea classes also
support the display of text using different foreground and background
colors. The following program shows how fonts and colors can be
quickly incorporated into a Java program to implement features
associated with what-you-see-is-what-you-get (WYSIWYG) editors.
The EditApp program shows
how the Font and Color
classes can be incorporated into the TextEdit
program introduced in Chapter 18, "Opening
Windows." Its source code is shown in Listing 22.2.
The EditApp program uses
the FontDialog and ColorDialog
classes that are introduced in subsequent sections. In order to
compile and run EditApp.java,
you will need to type in the FontDialog.java
and ColorDialog.java
files. Java will automatically compile the FontDialog.java
and ColorDialog.java files
when EditApp.java is compiled.
Listing 22.2. The source code of the EditApp
program.
import java.awt.*;
import java.io.*;
import jdg.ch20.*;
import jdg.ch22.FontDialog;
import jdg.ch22.ColorDialog;
public class EditApp extends Frame {
String programName;
Object menuItems[][] = {
{"File","New","Open","-","Save
As","-","Exit"},
{"Format","Font","Color"}
};
MyMenuBar menuBar = new MyMenuBar(menuItems);
TextArea text;
FileDialog openFile = new FileDialog(this,"Open File",FileDialog.LOAD);
FileDialog saveFile = new FileDialog(this,"Save File
As",FileDialog.SAVE);
FontDialog fd;
ColorDialog cd;
Font currentFont = new Font("Courier",Font.PLAIN,12);
Color currentColor = Color.black;
public static void main(String args[]){
EditApp app = new EditApp();
}
public EditApp() {
super("WYSIWYG Text Editor");
programName = getTitle();
setup();
pack();
resize(text.preferredSize());
show();
}
void setup() {
setBackground(Color.white);
text = new TextArea(25,80);
text.setFont(currentFont);
add("Center",text);
setMenuBar(menuBar);
setCursor(TEXT_CURSOR);
}
public void readFile(String file) {
DataInputStream inStream;
try{
inStream = new DataInputStream(new FileInputStream(file));
}catch (IOException ex){
notifyUser("Error opening file");
return;
}
try{
String newText="";
String line;
while((line=inStream.readLine())!=null)
newText=newText+line+"\n";
text.setText(newText);
inStream.close();
}catch (IOException ex){
notifyUser("Error reading file");
}
}
public void writeFile(String file) {
DataOutputStream outStream;
try{
outStream = new DataOutputStream(new FileOutputStream(file));
}catch (IOException ex){
notifyUser("Error opening file");
return;
}
try{
outStream.writeBytes(text.getText());
outStream.close();
}catch (IOException ex){
notifyUser("Error writing file");
}
}
public void notifyUser(String s) {
String text[] = {s};
String buttons[] = {"OK"};
new Notification(this,"Error",true,text,buttons);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
System.exit(0);
return true;
}else if(event.id==Event.GOT_FOCUS && !(event.target
instanceof TextArea)) {
setCursor(DEFAULT_CURSOR);
return true;
}else if(event.id==Event.LOST_FOCUS) {
setCursor(TEXT_CURSOR);
return true;
}else if(event.id==Event.ACTION_EVENT){
String arg = (String) event.arg;
if(event.target instanceof MenuItem){
if(processFileMenu(arg)) return true;
if(processFormatMenu(arg)) return true;
}else if(event.target instanceof Button){
if("Select".equals(arg)){
if(fd != null) {
if(fd.isChanged()) {
currentFont = fd.getFont();
fd.dispose();
text.setFont(currentFont);
}
}
if(cd != null) {
if(cd.isChanged()) {
currentColor = cd.getColor();
cd.dispose();
text.setForeground(currentColor);
text.setText(text.getText());
}
}
}
}
}
return false;
}
public boolean processFileMenu(String s) {
if("New".equals(s)){
text.setText("");
return true;
}else if("Open".equals(s)){
openFile.show();
String inFile = openFile.getFile();
readFile(inFile);
return true;
}else if("Save As".equals(s)){
saveFile.show();
String outFile = saveFile.getFile();
writeFile(outFile);
return true;
}else if("Exit".equals(s)){
System.exit(0);
return true;
}
return false;
}
public boolean processFormatMenu(String s) {
if("Font".equals(s)){
fd = new FontDialog(this,currentFont);
fd.show();
return true;
}else if("Color".equals(s)){
cd = new ColorDialog(this,currentColor);
cd.show();
return true;
}
return false;
}
}
class Notification extends MessageDialog {
public Notification(Frame parent,String title,boolean modal,String
text[],
String buttons[]) {
super(parent,title,modal,text,buttons);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
dispose();
return true;
}else if(event.id==Event.ACTION_EVENT && event.target
instanceof Button){
dispose();
return true;
}
return false;
}
}
The EditApp program displays
the opening window shown in Figure 22.2.
Figure 22.2 : The EditApp opening window.
Select Open from the File menu as shown in Figure 22.3
and use the Open File dialog box, shown in Figure 22.4,
to open the EditApp.java
source code file.
Figure 22.3 : The File menu.
Figure 22.4 : The Open File dialog box.
The text of the EditApp.java
source file is read into the program and displayed in the window
using a 12-point Courier font, as shown in Figure 22.5.
Figure 22.5 : Editing EditApp.java
Select the Font menu item from the Format menu to change the current
font used to display the text, as shown in Figure 22.6.
Figure 22.6 : The Format menu.
The Select a font: dialog box is displayed, as shown in Figure 22.7.
Use this dialog box to select a 14-point Bold Italic Helvetica
font, as shown in Figure 22.8.
Figure 22.7 : The Font dialog box.
Figure 22.8 : Selecting a new font.
The text's display is updated, as shown in Figure 22.9.
Figure 22.9 : Updated text.
Select the Color menu item from the Format menu. The Select a
color: dialog box is displayed, as shown in Figure 22.10.
Use this dialog box to change the color associated with the text's
display. Try using primary colors such as blue or yellow. Other
colors might not display correctly, depending on the number of
colors supported by your video card and the current color map
associated with the display.
Figure 22.10 : The color dialog box.
The EditApp program makes
use of the FontDialog and
ColorDialog classes, which
are covered in the following sections. The basic functionality
of the EditApp program remains
the same as the TextEdit
program. It has been streamlined to use the MyMenuBar
and MyMenu classes and adds
the fd and cd
variables to refer to the FontDialog
and ColorDialog objects created
by the program.
The setup() method specifies
that TEXT_CURSOR should be
used, by default, and extra event-handling code has been added
to switch between TEXT_CURSOR
and DEFAULT_CURSOR, depending
on whether the text is in the locus of the text area or the menu
bar.
The Notification class has
also been updated to take advantage of the MessageDialog
class.
The main changes to the EditApp
program are to its event handling. The GOT_FOCUS
event is handled by checking the target of the event to determine
whether it is the TextArea
object. If it is not, the cursor is changed to DEFAULT_CURSOR.
The cursor is changed back to TEXT_CURSOR
when it handles the LOST_FOCUS
event. This event is handled when the object getting the focus
is the TextArea object.
When an ACTION_EVENT occurs
whose target is an instance of the MenuItem
class, the processFileMenu()
and processFormatMenu() methods
are invoked to process the associated menu items. When ACTION_EVENT
is an instance of the Button
class, signifying a FontDialog
or ColorDialog selection,
the current objects associated with the fd
and cd variables are checked
to see which one is associated with an object. The isChanged()
methods of the dialog boxes are used to determine whether a font
or color change occurred. The getFont()
and getColor() methods are
used to set the currentFont
and currentColor variables,
the dialog boxes are disposed of using the dispose()
method of the Window class,
and the font, color, and text are set appropriately.
The processFileMenu() method
checks to see if the currently selected menu item is a File menu
item and processes it using the same approach as in the TextEdit
program. The processFormatMenu()
method checks for a Font or Color menu item and processes the
menu item by creating a new FontDialog
or ColorDialog object and
then displaying the dialog box using the show()
method of the Window class.
The FontDialog class provides
a handy encapsulation of the dialog boxes commonly used to select
a font from the list of available fonts provided by the system.
The source code of the FontDialog
class is shown in Listing 22.3.
Listing 22.3. The source code of the FontDialog
class.
package jdg.ch22;
import java.awt.*;
import jdg.ch21.MyList;
public class FontDialog extends Dialog {
String fontName;
int fontStyle;
int fontSize;
String fontNames[];
String styleNames[] = {"Plain","Bold","Italic","Bold
Italic"};
String sizeNames[] = {"10","12","14","18","24","36","72"};
int styles[] = {Font.PLAIN,Font.BOLD,Font.ITALIC,Font.BOLD+Font.ITALIC};
int sizes[] = {10,12,14,18,24,36,72};
MyList fontList;
MyList styleList = new MyList(5,false,styleNames);
MyList sizeList = new MyList(5,false,sizeNames);
Toolkit toolkit;
Font newFont;
boolean fontChanged;
public FontDialog(Frame parent,Font currentFont) {
super(parent,"Select a font:",true);
toolkit = parent.getToolkit();
newFont = currentFont;
setupFonts();
setupPanels();
setBackground(Color.lightGray);
setForeground(Color.black);
pack();
resize(preferredSize());
}
void setupFonts() {
fontName=newFont.getName();
fontStyle=newFont.getStyle();
fontSize=newFont.getSize();
fontNames = toolkit.getFontList();
fontList = new MyList(5,false,fontNames);
}
void setupPanels() {
Panel mainPanel = new Panel();
mainPanel.setLayout(new GridLayout(1,3));
Panel fontPanel = new Panel();
fontPanel.setLayout(new BorderLayout());
Label fontLabel = new Label("Font:");
fontPanel.add("North",fontLabel);
fontPanel.add("Center",fontList);
Panel stylePanel = new Panel();
stylePanel.setLayout(new BorderLayout());
Label styleLabel = new Label("Style:");
stylePanel.add("North",styleLabel);
stylePanel.add("Center",styleList);
Panel sizePanel = new Panel();
sizePanel.setLayout(new BorderLayout());
Label sizeLabel = new Label("Size:");
sizePanel.add("North",sizeLabel);
sizePanel.add("Center",sizeList);
mainPanel.add(fontPanel);
mainPanel.add(stylePanel);
mainPanel.add(sizePanel);
Font plainFont = new Font("Helvetica",Font.PLAIN,12);
Font boldFont = new Font("Helvetica",Font.BOLD,12);
mainPanel.setFont(plainFont);
fontLabel.setFont(boldFont);
styleLabel.setFont(boldFont);
sizeLabel.setFont(boldFont);
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(new Button("Select"));
buttonPanel.add(new Button("Cancel"));
buttonPanel.setFont(boldFont);
add("Center",mainPanel);
add("South",buttonPanel);
}
public boolean isChanged() {
return fontChanged;
}
public Font getFont() {
return newFont;
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
dispose();
return true;
}else if(event.id==Event.ACTION_EVENT) {
if(event.target instanceof Button) {
if("Select".equals(event.arg)) {
updateNewFont();
show(false);
return false;
}else if("Cancel".equals(event.arg)) {
dispose();
return true;
}
}
}
return false;
}
void updateNewFont() {
if(fontList.getSelectedIndex() != -1) fontName = fontList.getSelectedItem();
if(styleList.getSelectedIndex() != -1)
fontStyle = styles[styleList.getSelectedIndex()];
if(sizeList.getSelectedIndex() != -1)
fontSize = sizes[sizeList.getSelectedIndex()];
newFont = new Font(fontName,fontStyle,fontSize);
fontChanged = true;
}
}
The FontDialog class creates
the Font dialog box shown in Figure 22.7.
This type of dialog box is used in most text-processing applications.
You can reuse the FontDialog
class, as it is currently defined, in your Java programs. You
can also subclass FontDialog
and add your own custom enhancements.
The FontDialog class declares
a number of variables that are used in the generation and processing
of the Font dialog box. The fontName,
fontStyle, and fontSize
variables are used to keep track of the parameters of the currently
selected font. The fontNames[]
array identifies the names of the fonts that are currently supported
by the system. The styles[],
styleNames[], sizes[],
and sizeNames[] arrays are
used to maintain int and
String lists of the font
styles and sizes that are displayed in the dialog box. The fontList,
styleList, and sizeList
variables refer to the MyList
objects displayed in the dialog box. The toolkit
variable refers to the Toolkit
object of the window containing the Font dialog box. The fontChanged
variable keeps track of whether the user has selected a new font,
and the newFont variable
maintains the Font object
that is selected by the user.
The FontDialog constructor
uses the superclass constructor call statement to create a modal
dialog box with the title Select a font:. The toolkit associated
with the window containing the dialog box is obtained using the
getToolkit() method of the
Window class. The newFont
variable, representing the user's font selection, is set to the
default value of the currently selected font. This font is passed
to the FontDialog constructor
using the currentFont parameter.
The FontDialog constructor
invokes the setupFonts()
and setupPanels() methods
to perform the bulk of the dialog box setup. It then packs the
dialog box window and resizes it. Note that the constructor does
not invoke the show() method
to display the dialog box. The actual display of the dialog box
must be performed by the containing window.
The setupFonts() method assigns
default values to the fontName,
fontStyle, and fontSize
variables based on the values of the current font stored in the
newFont variable. The getFontList()
method of the Toolkit class
is used to set the fontNames[]
array to the list of fonts currently supported by the system.
These names are converted to a list using the MyList()
constructor.
The setupPanels() method
performs all the grunt work, adding the lists to the dialog box
and rearranging them in an appealing fashion. The mainPanel
variable is used to refer to the overall panel into which the
fontPanel, stylePanel,
and sizePanel objects are
inserted. The mainPanel is
laid out as a three-column set of subpanels. These subpanels are
identified by the fontPanel,
stylePanel, and sizePanel
variables. Each of these subpanels is laid out using a BorderLayout
object. The label identifying the contents of the panel is added
to the top of the panel. The center of each panel contains the
three MyList objects identified
by the fontList, styleList,
and sizeList variables.
The Helvetica font is used for the contents of the Font dialog
box. The labels at the top of each column are set in a boldface
style. A second panel, referred to by the buttonPanel
variable, is created with two buttons: Select and Cancel. These
buttons provide the user controls needed to accept or abort a
font selection. The mainPanel
is added to the center of the Font dialog box and the buttonPanel
is added to the bottom.
Two access methods are provided with the FontDialog
class. The isChanged() method
is used to query a FontDialog
object to determine whether the user made a font selection. The
getFont() method returns
the font selected by the user.
The events handled by FontDialog
consist of the WINDOW_DESTROY
event and the ACTION_EVENT
events associated with the Select and Cancel buttons. The use
of the WINDOW_DESTROY event
and Cancel button result in the destruction of the FontDialog
object. The object is destroyed using the dispose()
method of the Window class.
The Select button invokes the updateNewFont()
method to create a font based on the user's current list selections
and assign that font to the newFont
variable. The Font dialog box is then hidden but not destroyed.
The show() method of the
Component class is used to
hide the dialog box.
The updateNewFont() method
checks the MyList objects
referred to by the fontList,
styleList, and sizeList
variables to update the fontName,
fontStyle, and fontSize
variables based on the user's selection. These variables are then
used to construct a new Font
object, which is assigned to the newFont
variable. The fontChanged
flag is then set to indicate that a user font selection has occurred.
The ColorDialog class is
very similar to, but simpler than, the FontDialog
class. It allows the user to select a color from the list of colors
defined in the Color class.
It provides a dialog box that is similar to that of FontDialog,
but is much simpler because only one list-the list of available
color-is supported. The source code of the ColorDialog
class is shown in Listing 22.4.
Listing 22.4. The source code of the ColorDialog
class.
package jdg.ch22;
import java.awt.*;
import jdg.ch21.MyList;
public class ColorDialog extends Dialog {
Color colors[] = {Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,
Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,Color.red,
Color.white,Color.yellow};
String colorNames[] = {"black","blue","cyan","darkGray","gray","green",
"lightGray","magenta","orange","pink","red",
"white","yellow"};
MyList colorList = new MyList(5,false,colorNames);
Color newColor;
boolean colorChanged;
public ColorDialog(Frame parent,Color currentColor) {
super(parent,"Select a color:",true);
setupPanels();
setBackground(Color.lightGray);
setForeground(Color.black);
pack();
resize(preferredSize());
}
void setupPanels() {
Panel colorPanel = new Panel();
colorPanel.setLayout(new BorderLayout());
Label colorLabel = new Label("Color:");
colorPanel.add("North",colorLabel);
colorPanel.add("Center",colorList);
Font plainFont = new Font("Helvetica",Font.PLAIN,12);
Font boldFont = new Font("Helvetica",Font.BOLD,12);
colorLabel.setFont(boldFont);
colorList.setFont(plainFont);
Panel buttonPanel = new Panel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.add(new Button("Select"));
buttonPanel.add(new Button("Cancel"));
buttonPanel.setFont(boldFont);
add("Center",colorPanel);
add("South",buttonPanel);
}
public boolean isChanged() {
return colorChanged;
}
public Color getColor() {
return newColor;
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
dispose();
return true;
}else if(event.id==Event.ACTION_EVENT) {
if(event.target instanceof Button) {
if("Select".equals(event.arg))
{
if(colorList.getSelectedIndex()
!= -1)
newColor = colors[colorList.getSelectedIndex()];
colorChanged = true;
show(false);
return false;
}else if("Cancel".equals(event.arg))
{
dispose();
return true;
}
}
}
return false;
}
}
The ColorDialog class declares
the colors[] array as an
array of color constants and the colorNames[]
array as the names associated with these color constants. The
colorList variable refers
to the MyList object that
presents the colorNames[]
array to the user. The newColor
variable identifies the color selected by the user, and the colorChanged
variable indicates whether a user color selection has been made.
The ColorDialog constructor
invokes the Dialog constructor
to set the title of the dialog box. It then invokes the setupPanels()
method to perform most of the setup of the dialog box's internal
components. The foreground and background colors are set and then
the dialog box is packed and resized.
The setupPanels() method
creates and adds two panels to the dialog box. These panels are
identified by the colorPanel
and buttonPanel variables.
The panel identified by the colorPanel
variable contains the Color: label and the MyList
object referred to by the colorList
variable. The button panel is implemented in the same manner as
in the FontDialog class.
The isChanged() and getColor()
methods are used to determine whether the user has selected a
color and, if so, to return the color selected.
The WINDOW_DESTROY event
and the clicking of the Cancel button are handled by invoking
the dispose() method of the
Window class. This causes
the dialog box to be destroyed and its resources to be returned
to the system. The clicking of the Select button is handled by
invoking the getSelectedIndex()
method of the List class
to see if a color was selected and setting the newColor
variable to the selected color. The colorChanged
flag is updated to indicate that a color has been selected and
the show() method causes
the dialog box to be hidden.
Summary
This chapter covers the details of using the text- and font-related
classes. It shows you how to use the text-based classes provided
by Java and how to display text with the canvas. It also explains
how the Font and FontMetrics
classes are used to provide custom control of text display. Chapter 23,
"The Canvas," covers the Canvas
and Graphics classes.

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.