developer.com - Reference
Click here to support our advertisers
SHOPPING
JOB BANK
CLASSIFIEDS
DIRECTORIES
REFERENCE
Online Library
LEARNING CENTER
JOURNAL
NEWS CENTRAL
DOWNLOADS
COMMUNITY
CALENDAR
ABOUT US
Journal:
Get the weekly email highlights from the most popular journal for developers!
Current issue
developer.com
developerdirect.com
htmlgoodies.com
javagoodies.com
jars.com
intranetjournal.com
javascripts.com
All Categories :
Java
Chapter 18
Opening Windows
CONTENTS
Hello Windows!
Going Round in Ovals: A Graphics Program
A Text Editor
Summary
This chapter is the first of eight chapters that cover window
programming. It introduces you to Java windows by way of several
examples that illustrate different aspects of the classes and
methods used to implement simple window applications. Its purpose
is to quickly get you up to speed developing window-based programs.
Subsequent chapters will fill in the details of the classes and
methods that are introduced here. You should approach this chapter
by trying to get a good general understanding of what is going
on in the sample programs without dwelling on the details. You
will learn the details when you study them in later chapters.
Hello
Windows!
The first program you wrote in Chapter 4,
"First Programs: Hello World! to BlackJack," is the
HelloWorldApp program. It displays the traditional Hello
World! text to the console window. The main purpose of the
program was to show you how to develop a simple Java program that
actually produced some noticeable effect. The same rationale applies
to the HelloWindowsApp program that you'll develop shortly.
The program shows you how to open an application window and write
the text Hello Windows! to the window. The code for the
HelloWindowsApp program is shown in Listing 18.1.
Listing 18.1. The source code of the HelloWindowsApp
program.
import java.awt.Frame;
import java.awt.Event;
import java.awt.Graphics;
public class HelloWindowsApp extends Frame {
public static void main(String args[]){
HelloWindowsApp app = new HelloWindowsApp();
}
public HelloWindowsApp() {
super("Hello Windows!");
pack();
resize(200,200);
show();
}
public void paint(Graphics g) {
g.drawString("Hello Windows!",50,90);
}
public boolean handleEvent(Event event) {
if(event.id==Event.WINDOW_DESTROY){
System.exit(0);
return true;
}else return false;
}
}
When you compile and run the program it opens a small window in
the upper-left corner of your desktop and displays the text Hello
Windows! in the middle of the window. This program is no
giant feat for mankind, but it's a large step for you. It marks
your transition from console to window-based programs. Up to this
point in the book, console programs served admirably in helping
cover the different aspects of the Java language and many of the
classes of the API. However, window-based programs and applets
(which you learn about in Part VI, "Programming the Web with
Applets and Scripts") are the primary areas of interest for
most Java programmers. Figure 18.1 shows
the window displayed by the HelloWindowsApp program.
Figure 18.1 :The HelloWindowsApp program display.
Let's take a look at HelloWindowsApp and find out what
makes it work. You probably noticed right off the bat that we
are now importing classes from the java.awt package.
The Frame, Event, and Graphics classes
shown in the import statements are classes that are fundamental
to developing window programs. The Frame class is used
to create Frame objects that implement application main
windows. The Event class is used to process user-generated
interface events, such as mouse clicks and keyboard input, and
the Graphics class is used to update the screen display.
The HelloWindowsApp class extends the Frame
class. This is a typical approach to developing window programs.
By subclassing Frame, your application class implements
a main application window. You still use the same old main()
method for implementing the entry point to your program. In HelloWindowsApp,
the main() method simply creates a default object of
class HelloWindowsApp.
The HelloWindowsApp constructor uses the super()
constructor call statement to invoke the Frame constructor
with the string "Hello Windows!". The Frame
constructor creates a new application window frame with the specified
text as its title. The pack() method is used to pack
the components of the window and set the window's size based upon
the size of these components. It is inherited from the Window
class, which is the superclass of Frame. The resize()
method then resizes the window to a 200¥200
pixel dimension. The resize() method is inherited from
the Component class by way of the Container,
Window, and Frame classes. Finally, the show()
method is used to cause the window to be displayed. It is inherited
from the Window class.
You might be wondering how the "Hello Windows!"
text is actually displayed because there is no call from main()
or HelloWindowsApp() to the paint() method.
When a window or any other object that is in a subclass of Component
is initially displayed or redisplayed as the result of the window
being uncovered or brought to the foreground, the paint()
method is invoked. It then paints the window according to the
current application state.
The paint() method used by HelloWindowsApp overrides
the paint() method inherited from the Component
class. It takes a Graphics object as a parameter. The
Graphics class provides numerous easy-to-use methods
for drawing on Graphics objects. The paint()
method uses the drawString() method to display the text
"Hello Windows!" at the screen coordinate 50,90
within the application window.
Window coordinates are organized with the upper-left corner of
the window being 0,0. The coordinates of the upper-right corner
of the window are width,0, where width is the horizontal
width of the window in pixels. The coordinates of the lower-left
corner of the window are 0,height, where height
is the vertical height of the window in pixels. Finally, the coordinates
of the lower-right corner of the window are width,height.
Figure 18.2 illustrates the window coordinate
system.
Figure 18.2 :Window coordinates.
You probably have been wondering what the handleEvent()
method is doing in the HelloWindowsApp class. The handleEvent()
method provides a standard approach to event handling in Java
applications. Events represent actions that occur during
the course of program execution. Most events are generated as
the result of user actions such as mouse clicks and keyboard actions.
The handleEvent() method overrides the method inherited
from the Component class. It takes an object of the Event
class as a parameter and uses the methods and constants of the
Event class to determine what event was passed to it
and how it should be handled. The handleEvent() method
returns a boolean value indicating whether or not the
event has been handled. If a false value is returned,
the event is propagated to the handleEvent() method of
the parent of the class that is currently handling the event.
If a true value is returned, no further event propagation
takes place.
The handleEvent() method of HelloWindowsApp
checks the id variable of the event to see if it equals
the constant Event.WINDOWS_DESTROY. The id variable
and the WINDOWS_DESTROY constant both are defined in
the API of the Event class. The id variable
is used to identify what type of event occurred, and the Event
class constants specify the event types. In this example, the
event handler only handles the WINDOW_DESTROY event.
This event occurs when the user closes the main application window
by clicking the Close Window icon, as shown in Figure 18.3.
Figure 18.3 :Terminating the HelloWindowsApp program.
The WINDOW_DESTROY event is handled by invoking the exit()
method of the System class to terminate the program.
The true value is returned to indicate that the event
was handled.
You might be wondering what would happen if the event handler
did not handle the WINDOW_DESTROY event. Try deleting
the handleEvent() method and recompiling and rerunning
HelloWindowsApp to see what happens when you try to terminate
the application.
Going
Round in Ovals: A Graphics Program
The HelloWindowsApp program provided a simple introduction
to window programming. It illustrated many of the basics of writing
a window program, but it didn't actually do all that much.
The OvalApp program is also an introductory window program.
It introduces more window programming classes and methods such
as panels, buttons, layouts, additional event handling, and, of
course, oval drawing. The source code of OvalApp is shown
in Listing 18.2.
Listing 18.2. The source code of the OvalApp
program.
import java.awt.*;
import java.util.Random;
public class OvalApp extends Frame {
int screenWidth = 400;
int screenHeight = 400;
Oval oval;
public static void main(String args[]){
OvalApp app = new OvalApp();
}
public OvalApp() {
super("Let's Draw Ovals!");
Panel buttons = new Panel();
buttons.add(new Button("Next"));
buttons.add(new Button("Quit"));
add("South",buttons);
oval = new Oval(screenWidth,screenHeight);
pack();
resize(screenWidth,screenHeight);
show();
}
public void paint(Graphics g) {
oval.paint(g);
}
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 Button){
if("Next".equals(event.arg)){
oval.update();
repaint();
return true;
}else if("Quit".equals(event.arg)){
System.exit(0);
return true;
}
}
}
return false;
}
}
class Oval {
int x, y, width, height, maxWidth, maxHeight;
Color color;
static Random r = new Random();
public Oval(int w,int h) {
super();
maxWidth = w;
maxHeight = h;
update();
}
public void update() {
x = Math.abs(r.nextInt() % (maxWidth-100));
y = Math.abs(r.nextInt() % (maxHeight-100));
width = (maxWidth - x)/3;
height = (maxHeight - y)/3;
int rgb[] = new int[3];
for(int i=0;i<3;++i) rgb[i]=Math.abs(r.nextInt()%256);
color = new Color(rgb[0],rgb[1],rgb[2]);
}
public void paint(Graphics g) {
g.setColor(color);
g.fillOval(x,y,width,height);
}
}
When you run the OvalApp program it displays a window
with the title Let's Draw Ovals!. A colored oval is displayed
somewhere in the application window, as shown in Figure 18.4.
Figure 18.4 : The OvalApp startup display
The window has two buttons, labeled Next and Quit. When you click
on the Next button, as shown in Figure 18.5,
a different oval is displayed.
Figure 18.5 : The Next button.
You can continue to click on the Next button to cause different
colored ovals to be displayed in different parts of the window,
as shown in Figure 18.6.
Figure 18.6 : A new oval is displayed.
When you have thoroughly amused yourself by drawing ovals, you
can click on the Quit button, as shown in Figure 18.7,
and terminate the program's execution.
Figure 18.7 : The Quit button.
The OvalApp program is cute and entertaining, but doesn't
perform any useful processing. However, it does provide a good
example of some new window programming constructs.
The program begins by doing an import of the relevant classes
of the java.awt package. The program uses a large number
of java.awt classes and, rather than listing each one
individually, uses the more general package import statement
to eliminate the trouble of typing each one in individually. The
only other class that is included is the Random class
of the java.util package. This class provides the capability
to generate random numbers to be used in the oval drawing.
The OvalApp class extends Frame in the same
manner as the HelloWindowsApp. Three variables are defined
for the OvalApp class. The screenWidth and screenHeight
variables define the dimensions of the main window. The oval
variable is used to refer to the current Oval object
being displayed. The main() method simply creates a new
object of class OvalApp.
The OvalApp constructor sets the window title using the
superclass constructor call statement, super(). It then
creates a Panel object called buttons. Panels
are window objects that are used as containers for other objects.
They help to organize the way GUI controls are placed in windows.
The buttons panel will be used to organize the Next and
Quit buttons. The add() method is used with buttons to
add two new objects of class Button to the panel. The
Button constructor takes a string argument that is the
label for the buttons. The add() method is then invoked
for the OvalApp object being constructed to add the panel
to the OvalApp application window. The OvalApp
add() method is inherited from the Container
class. The "South" string identifies where
the panel should be added in the application window.
The organization of objects within a window container is governed
by the layout of the container. (Layouts are described
in detail in Chapter 19, "Organizing
Window Programs.") The default layout for Frame
objects and their subclasses is BorderLayout. This type
of layout organizes objects within a container by their North,
South, East, and West borders. Objects can also be placed in the
Center of a container. The add("South",buttons);
method invocation adds the buttons panel to the southern
(bottom) border of the OvalApp window.
The buttons panel is also associated with a layout. Panels
use a FlowLayout object, by default. The FlowLayout
class organizes objects in a container in a left-to-right fashion,
fitting as many objects as possible in a row before moving on
to fill the next row.
The oval variable is assigned a new object of class Oval
that is parameterized by the screenWidth and screenHeight
dimensions. These arguments are passed to the Oval constructor
to make sure that an Oval object is created that is appropriate
for the screen size of the OvalApp window. The Oval
class is discussed after the OvalApp class's description
is completed.
After adding the buttons panel to the window and creating
an Oval object, the pack() method is invoked
to organize the components of the window and to determine the
minimum preferred size of the window. The resize() method
then adjusts the screen to the specified width and height dimensions.
Finally, the show() method causes the window to be displayed.
The paint() method for the OvalApp class simply
passes the task of drawing the window to the Oval class.
Notice that it passes on the Graphics object that it
receives to the Oval paint() method. Without
the Graphics object, Oval's paint()
method would have nothing to draw on.
The handleEvent() method for OvalApp doesn't
fare as well as the paint() method. Instead of handing
off its processing to other classes, it provides a central point
for all program event handling. It processes the WINDOWS_DESTROY
event in the same manner as the HelloWindowsApp program.
It also checks for events of type ACTION_EVENT. Events
of this type are typically generated by performing actions on
GUI controls-for example, clicking on a button, selecting a menu
item, or checking a checkbox. In this case, the method is checking
whether the Next or Quit button was clicked. It does this by checking
the target variable of the event to see if it is an instance
of class Button. The target variable identifies
the object that is the target of the event being processed.
The event.arg variable is event specific. It typically
provides a value that is used to identify the specific object
from its class for which the event was generated. In the case
of Button objects, it represents the label of the button.
The arg variable is used to determine whether the button
being clicked on is the Next button or the Quit button.
When the Next button is clicked, the button-clicked event is handled
by invoking the update() method of the oval
variable and repainting the screen. The update() method
causes the oval's color, position, and size parameters to be changed.
The repaint() method results in the paint()
method being reinvoked to redraw an object-in this case, the OvalApp
window. You should never invoke paint() directly-it is
under the control of the native windows implementation. Always
access it by invoking repaint().
When the Quit button is clicked, the OvalApp program
terminates in the same manner as when the WINDOW_DESTROY
event occurs.
The Oval class is used to randomly generate ovals of
different colors, sizes, and positions and display them in the
OvalApp window. It defines a number of variables that
specify these parameters. The maxWidth and maxHeight
variables store the dimensions of the application window. The
width and height parameters store the actual
width and height of an Oval object. The x and
y parameters identify its position within the application
window. The color parameter identifies the color in which
the oval is to be drawn. The static r variable is an
object of class Random that is used to generate random
numbers that determine the oval's characteristics.
The Oval constructor explicitly calls the default constructor
call statement, sets the maxWidth and maxHeight
variables, and invokes its update() method to randomly
generate the values of the rest of the variables defined by the
Oval class.
The update() method sets the upper-left corner of the
oval to a random value between (0,0) and (maxWidth=100,maxHeight=100).
This keeps the oval from scrunching up against the window's borders.
The width and height of the rectangle are set to one-third of
the distance between the upper-left corner of the rectangle and
the lower-right corner of the application window.
The red, blue, and green color intensities of the rectangle are
randomly generated as values between 0 and 255. In order for the
full range of color values to be displayed, your screen must support
24-bit color in its current screen resolution; otherwise, the
randomly generated color will be approximated by the next closest
color supported by your video card. I rarely set my screen to
24-bit color and usually use 8-bit color to cut down on my video-display
memory requirements.
The paint() method of the Oval class uses the
Graphics object passed to it by the OvalApp
paint() method to display the oval. It sets the current
color of the Graphics object based on the randomly generated
color stored in the color variable. It then invokes the
fillOval() method of the Graphics class to draw
an oval that is filled with the current color. The fillOval()
method takes the upper-left corner of the Oval and its
width and height dimensions as parameters.
A Text
Editor
Now let's extend your exploration of window applications by developing
a primitive text editor. The TextEditApp program illustrates
more window programming constructs. It introduces menus, dialog
boxes, fonts, text processing, and window-based file I/O. It also
builds on the event-handling skills that you've developed so far.
The source code of the TextEditApp program is shown in
Listing 18.3.
Listing 18.3. The source code of the TextEditApp
program.
import java.awt.*;
import java.io.*;
public class TextEditApp extends Frame {
TextArea text;
MenuBar menuBar;
FileDialog openFile;
FileDialog saveFile;
public static void main(String args[]){
TextEditApp app = new TextEditApp();
}
public TextEditApp() {
super("Text Editor");
setup();
resize(text.minimumSize());
pack();
show();
}
void setup() {
setFont(new Font("System",Font.PLAIN,12));
setBackground(Color.white);
text = new TextArea(25,80);
add("Center",text);
setupMenuBar();
openFile = new FileDialog(this,"Open File",FileDialog.LOAD);
saveFile = new FileDialog(this,"Save File As",FileDialog.SAVE);
}
void setupMenuBar(){
menuBar = new MenuBar();
Menu fileMenu = new Menu("File");
fileMenu.add(new MenuItem("New"));
fileMenu.add(new MenuItem("Open"));
fileMenu.addSeparator();
fileMenu.add(new MenuItem("Save As"));
fileMenu.addSeparator();
fileMenu.add(new MenuItem("Exit"));
menuBar.add(fileMenu);
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("New".equals(event.arg)){
text.setText("");
return true;
}else if("Open".equals(event.arg)){
openFile.show();
String inFile = openFile.getFile();
readFile(inFile);
return true;
}else if("Save As".equals(event.arg)){
saveFile.show();
String outFile = saveFile.getFile();
writeFile(outFile);
return true;
}else if("Exit".equals(event.arg)){
System.exit(0);
return true;
}
}
}
return false;
}
public void readFile(String file) {
DataInputStream inStream;
try{
inStream = new DataInputStream(new FileInputStream(file));
}catch (IOException ex){
notifyDialog("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){
notifyDialog("Error reading file");
}
}
public void writeFile(String file) {
DataOutputStream outStream;
try{
outStream = new DataOutputStream(new FileOutputStream(file));
}catch (IOException ex){
notifyDialog("Error opening file");
return;
}
try{
outStream.writeBytes(text.getText());
outStream.close();
}catch (IOException ex){
notifyDialog("Error writing file");
}
}
public void notifyDialog(String msg) {
Notification notification = new Notification(this,msg);
notification.show();
}
}
class Notification extends Dialog {
String msg;
public Notification(Frame f,String s) {
super(f,"Notification",true);
msg = s;
}
public void show() {
add("North",new Label(msg,Label.CENTER));
Panel p = new Panel();
p.add(new Button("OK"));
add("South",p);
setBackground(Color.gray);
resize(160,100);
super.show();
}
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("OK".equals(event.arg)){
dispose();
return true;
}
}
}
return false;
}
}
The TextEditApp program provides quite a bit more functionality
than the other window programs that you've written so far. After
you've compiled it, run the program. It will begin by launching
a blank text-editing window with the Text Editor title, as shown
in Figure 18.8.
Figure 18.8 : The TextEditApp opening window.
Click in the editor window and begin experimenting with editing
text. Type in whatever text comes to your mind. Experiment with
tabs to see how they work. Try typing past the right margin to
see how the horizontal scrollbars work. Select text with your
cursor and use the keyboard copy, cut, and paste commands. Double-click
on a word to select it, and then type another word over it. Try
typing a few lines to cause the vertical scrollbars to come into
play. Your screen should look somewhat similar to Figure 18.9.
Figure 18.9 : Editing text
When you have finished editing the text, check out the File pull-down
menu shown in Figure 18.10. You'll notice
that the File menu supports four commands and contains two separator
lines that help organize these commands.
Figure 18.10 : The File pull-down menu
Save your text in the file test.txt. A File Save As dialog
box appears to help you save your file. The Windows 95 implementation
of Java displays a dialog box, as shown in Figure 18.11.
If you are using Java on another operating system, the dialog
box will look different.
Figure 18.11 : Saving text to a file.
After you have saved your file, select New from the File menu.
A new text-editing buffer is displayed. Having cleared the buffer,
select Open from the File menu and open the test.txt
file that you just saved. (See Figure 18.12.)
This file will be read in and loaded into the text-editing buffer.
Figure 18.12 : Opening a file.
If this seems like a lot of functionality for two pages of code,
you're right. Java does most of the work for you. You just need
to invoke the correct methods for the java.awt API classes.
Let's explore the TextEditApp program to see how it works.
You'll first notice that it imports the classes of the java.awt
and java.io classes. The java.awt package provides
the required window classes, and the java.io package
provides needed file I/O classes.
TextEditApp follows the lead of the other window programs
developed earlier in this chapter and subclasses the Frame
class. It declares four field variables: text, menuBar,
openFile, and saveFile. The text variable is
of class TextArea. It holds the object that implements
the functionality of the text-editing buffer. The menuBar
variable sets up the File menu. The openFile and saveFile
variables support the file dialog boxes shown in Figures 18.11
and 18.12.
The main() method simply creates an object of TextEditApp.
The TextEditApp constructor sets the window title using
the constructor of the Frame class and then invokes its
setup() method to set up all the objects in the TextEditApp
window. The resize() method is called to size the application
window based on the minimum size required to implement the TextArea
object assigned to text. The pack() and show()
methods complete the TextEditApp window setup and display.
The setup() method sets the font to be used in the TextArea
object, changes the window's background color, and then sets up
the TextArea object, the menu bar, and the file dialog
boxes. The setFont() method sets the current font to
a newly constructed font. It is inherited from the Component
class. The Font class constructor used to create the
new font uses the font name (System), text type (PLAIN),
and point size (12) of the font as parameters. The Font
class defines a number of font parameters that can be used in
constructing new font variations.
The setBackground() method sets the background color
to white. It is inherited from the Component class. The
Color class provides a number of predefined color constants.
The text variable is assigned an object of class TextArea
that is at least 25 rows by 80 columns. This object implements
most of the text-editing capabilities of TextEditApp.
It is then added to the center of the TextEditApp window.
The setupMenuBar() method is called to set up the File
menu.
The openFile and saveFile FileDialog
variables are assigned newly created FileDialog objects.
The FileDialog constructor takes three arguments. The
first is the window that "owns" the dialog box. This
is the window to which the file dialog box is attached. The window
is attached to the TextEditApp object created by the
main() method, so the this argument is supplied
to identify the current TextEditApp object. The second
parameter is the text string to be displayed at the top of the
dialog box. Refer to Figures 18.11 and
18.12 to see how the text string is
displayed. The third parameter is either the FileDialog.LOAD
or the FileDialog.SAVE constant, indicating whether a
file is to be loaded from disk or saved to disk.
The setupMenuBar() method shows how menu bars are created
and added to a window. The menuBar variable is assigned
an object of class MenuBar. A Menu object is
created with the File label and assigned to the fileMenu
variable. Menu items and separators are then added to the menu.
A Menu object represents a single pull-down menu. A MenuItem
object is a pull-down menu selection. A MenuBar object
is a collection of Menu objects that is attached to a
window.
The MenuItem objects are assigned a label when they are
created. They are added to the fileMenu in a top-down
fashion. The addSeparator() method is used to add a separator
line to a menu. Refer to Figure 18.10
to see how the resulting File menu is displayed. The fileMenu
is added to the menuBar object using the add()
method of the MenuBar class. The resulting menu bar is
added to the TextEditApp window using the setMenuBar()
method inherited from the Frame class.
At this point you might have noticed that the TextEditApp
class has no paint() method. The TextArea object
takes care of drawing itself and does not require an external
paint() method. TextArea is a remarkably self-contained
and easy-to-use class. Without TextArea, implementing
TextEditApp would be considerably more difficult.
The handleEvent() method handles more events than in
previous examples. It handles the WINDOW_DESTROY event
in the usual manner. This editor is just a prototype-a complete
text editor would prompt the user to save any changes before terminating
the application. All other events processed are of type ACTION_EVENT
and have as their target objects of class MenuItem. In
other words, these events process selections from the File menu.
MenuItem objects are distinguished by their labels as
supplied to the arg variable of an event.
The handling of the New menu item invokes the setText()
method of the TextArea class to delete all text in the
text variable. The handling of the Open menu
item invokes the show() method for the openFile
FileDialog, causing the dialog box to be displayed. The
getFile() method is invoked to get the name of the file
selected for opening by the user. The returned string is then
passed to the readFile() method of TextEditApp.
The handling of the Save As menu item is similar to that of the
Open menu item. The saveFile FileDialog is displayed.
A filename is returned and then passed to the writeFile()
method of the TextEditApp class. The Exit menu item is
handled in the same way as the WINDOW_DESTROY event.
Again, a complete editor would prompt the user to save changes
before exiting.
The readFile() method reads the file whose name was retrieved
via the openFile FileDialog. It first opens
the file by creating a new FileInputStream object using
the filename and then filtering this stream as a DataInputStream
object. The resulting input stream is then assigned to the inStream
variable. The try statement has a catch clause
that checks for the occurrence of an IOException. If
an exception occurs, the notifyDialog is used to warn
the user. It displays a dialog box as shown in Figure 18.13.
You can cause this dialog box to be generated by trying to open
a non-existent file. Try it!
Figure 18.13 : The Notification dialog box.
After the file has been opened, its text is read in a line at
a time and appended to the newText variable. This results
in the input being placed in one long string. The setText()
method of the TextArea class is used to move the text
into the TextArea object assigned to the text variable.
Any I/O errors occurring while the file is being read result in
the display of a notification dialog box with the Error reading
file message.
The writeFile() method operates in a similar but reverse
manner than the readFile() method. It uses the filename
retrieved via the saveFile FileDialog to create
a FileOutputStream object. It then filters this stream
as a DataOutputStream and assigns it to the outStream
variable. If any errors occur in the creation of these streams,
a dialog box is displayed with the message Error opening file.
After opening the file, the writeBytes() method of the
DataOutputStream class is invoked to write the data stored
in the TextArea object assigned to the text
variable to the output stream. The close() method is
then invoked to close the output stream. Any write errors result
in the display of an error-notification dialog box.
The notifyDialog() method supports the generation and
display of dialog boxes by creating new instances of the Notification
class and passing them the error message. It then invokes their
show() method to display them.
The Notification class actually implements the dialog
boxes that are displayed when an error occurs by extending the
Dialog class. The Dialog class, like the Frame
class, extends the Window class. It provides a different
set of methods to display dialog boxes as opposed to main application
windows. It has one variable, msg, that stores the message
to be displayed in the dialog box. Its constructor takes two arguments:
the application window object to which it is attached and the
message to be displayed. It invokes the Dialog class
constructor using the superclass constructor call statement and
passes it the Frame object, the string "Notification"
to be used as the title of the dialog box, and the true
boolean value, which determines whether the dialog box
will be modal. A modal dialog box is one that must be closed
before the user can return to the main application window. (Java
currently does not implement this blocking feature of modal dialog
boxes.) The constructor then saves the error message argument
in the msg variable.
The show() method of the Notification class
causes the dialog box to be displayed. It first creates an object
of class Label with the contents of the msg
variable being the text assigned to the Label object.
The Label.CENTER constant is used to center the text
in the Label object. The new label is then added to the
North end of the dialog box. Dialog
objects, like Frame objects, use a BorderLayout
object by default. A Panel object is then created, and
the OK button is created and added to the panel. The panel is
added to the South end of the dialog box. The single button was
placed in the panel to cause the button into be displayed in its
default dimensions. Instead of the button being stretched to fit
the dialog box, the panel in which the button resides is stretched.
To see this, try directly inserting the button to the dialog box
without using a panel. The background color of the dialog box
is set to gray using the setBackground() method inherited
from the Component class and the Color class
constants. The window is resized to 160¥100
pixels and then displayed using the show() method of
the Dialog class. The super keyword is used
to indicate that the show() method of the superclass
(Dialog) should be used instead of the show()
method of the current class (Notification).
The Notification class handles its
own events by overriding the handleEvent() method. The
WINDOW_DESTROY event is generated for a dialog box when
the user tries to directly close the dialog box without using
any of the dialog box buttons. This event is different from the
event generated for the main application window. The Notification
event handler handles the WINDOW_DESTROY event by invoking
the dispose() method inherited from the Window
class. The dispose() method causes the dialog window
to be closed and its resources to be returned to the system. The
handleEvent() method handles the OK button click by looking
for an event with an id set to ACTION_EVENT,
checking its target to make sure that it is an instance of the
Button class and checking its arg variable to
make sure that it is the OK button. It then invokes the dispose()
method to close the dialog box.
Summary
This chapter introduces you to window programming by way of several
sample programs that illustrate the classes and methods used to
implement simple window applications. You should now be comfortable
with analyzing window-based programs. Subsequent chapters fill
in the details of the classes and methods introduced here. They
will help you to become proficient in developing your own window
programs. Chapter 19 lays the framework
for developing window programs by expanding on the basics introduced
here.
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.
Wyszukiwarka
Podobne podstrony:
11 (311)ZADANIE (11)ch18Psychologia 27 11 2012359 11 (2)11PJU zagadnienia III WLS 10 11Wybrane przepisy IAAF 10 1106 11 09 (28)info Gios PDF Splitter And Merger 1 11więcej podobnych podstron