Você está na página 1de 65

UNIT IV INTRODUCING THE AWT

Working with Frame Windows Graphics Fonts Text AWT Control Layout Manager Menus Dialog Boxes

INTRODUCTION TO THE AWT


The classes and interfaces of the Abstract Windowing Toolkit (AWT) are used to develop stand-alone applications and to implement the GUI controls used by applets. These classes support all aspects of GUI development, including event handling. The Component and Container classes are two of the most important classes in the java.awt package. The Component class provides a common super class for all classes that implement GUI controls. The Container class is a subclass of the Component class and can contain other AWT components. The Window class is a subclass of the Container class that provides a common set of methods for implementing windows. The Window class has two subclasses, Frame and Dialog, that are used to create Window objects. The Frame class is used to create a main application window, and the Dialog class is used to implement dialog boxes. Major components you can work with in the awt:

Containers. Containers are generic awt components that can contain other components, including other containers. The most common form of container is the panel, which represents a container that can be displayed onscreen. Applets are a form of panel (in fact, the Applet class is a subclass of the Panel class).

Canvases. A canvas is a simple drawing surface. Although you can draw on panels (as you've been doing all along), canvases are good for painting images or performing other graphics operations.

UI components. These can include buttons, lists, simple pop-up menus, check boxes, test fields, and other typical elements of a user interface.

Window construction components. These include windows, frames, menu bars, and dialog boxes.

The classes inside the java.awt package are written and organized to mirror the abstract structure of containers, components, and individual UI components.

CLASS HIERARCHY OF AWT PACKAGE The class hierarchy that makes up the main classes in the awt. The root of most of the awt components is the class Component, which provides basic display and event-handling features. The classes Container, Canvas, TextComponent, and many of the other UI components inherit from Component. Inheriting from the Container class are objects that can contain other awt components-the Panel and Window classes, in particular. The java.applet.Applet class, even though it lives in its own package, inherits from Panel, so your applets are an integral part of the hierarchy of components in the awt system.

Partial awt Class Hierarchy In addition to the components themselves, the awt also includes a set of layout managers. Layout managers determine how the various components are arranged when they are displayed onscreen, and their various sizes relative to each other. Because Java applets and applications that use the awt can run on different systems

with different displays, different fonts, and different resolutions, you cannot just stick a particular component at a particular spot on the window. Layout managers help you create UI layouts that are dynamically arranged and can be displayed anywhere the applet or application might be run.

Designing Window Programs The design of most window programs usually involves two basic steps: laying out the program's graphical user interface and providing the functionality that implements the interface. The first step addresses one of the most important features of window programsits look and feel. Window programs are preferred to console programs when their look and feel are interesting, innovative, and help the user to accomplish a particular purpose. A program's look is determined by how it presents itself to users. It consists of all those characteristics that determine its appearance, such as window size, layout, background and foreground colors, menus, and GUI controls. A program's feel is determined by the availability of easy-to-use GUI controls and the contribution of these controls to the program's ultimate intended use. It is the result of the designer's ability to select and implement those GUI controls that enhance a program's capability to satisfy user expectations. The window's GUI design begins by creating an application window, using the
Frame

class, and determining the basic characteristics of the window such as its

size, title, background and foreground colors, and general layout. Next a menu bar is added to the window, and the program's menus and menu items are added to the menu bar. The GUI controls that are to be used in the window are determined, designed, and attached to the window's panels and frame. At this point, you know what your program will look like and you can concentrate on what it will do. The first step in bringing your program's user interface to life is to add the event-handling software required to respond to events generated as the

result of user interaction. The event-handling software will not immediately implement all user actions, but it should respond to them and provide hooks for eventual implementation of all user interface actions. The event-handling software is then fleshed out to provide all the functionality required of the application program. The program's design and implementation reaches an Alpha stage when all required user-interface functions have been implemented. The next stage of program development is to refine and test the program to make it more responsive to its intended purpose. A series of Beta versions of the program are developed that implement user feedback and fix any identified errors or deficiencies. Finally, the program is refined to handle unusual user inputs and to process errors and exceptions. An overview of the process of designing and implementing window programs. This chapter covers the basics of creating and organizing window programs and shows how to connect event-handling code to general window components. A window sampler program is provided that illustrates the basic use of common window GUI controls. Subsequent chapters explore the use of these GUI controls in more detail. Opening and Closing Windows Opening and closing windows mark the beginning and end of any window program. The Frame class provides the basis by which these fundamental window operations are accomplished. A Frame object implements an application main window, inheriting many methods that enable it to do so from the Window,
Container,

and Component classes.

To open an application window, a Frame object is created and its show() method is invoked. The show() method is inherited from the Window class. To close an application window, the WINDOW_DESTROY event must be handled. The window is disposed of using the dispose() method of the Window class, or more commonly by invoking the System.exit() method after performing any necessary programtermination processing.

The Frame class and its ancestors provide a number of methods that control the way in which a window is displayed. The setBackground() and setForeground() methods inherited from the Component class are used to specify a window's background and foreground colors. The setFont() method, also inherited from
Component,

is used to specify the default font to be used with a window. The Frame

class, itself, provides a number of methods that control a window's appearance. The setTitle() method allows a window's title to be changed. The setCursor() method allows the cursor to be changed while it is in the window's focus. The setMenuBar() method enables a menu bar to be attached to a window, and the setResizable() method toggles whether a window can or cannot be resized. The setIconImage() method allows the window's minimized icon to be changed.

The process for window design and implementation.

WORKING WITH FRAME WINDOWS


Frames are very useful in more complex applications. Frames let you separate different functions or data into different windows. For instance a painting application may have several different pictures in varying states of completion open in different windows. Or it may have only one picture but a separate window might contain a tool palette to select different brushes or colors. Each of these windows would be a Frame. Everything you need to create and work with frames is contained in the java.awt.Frame class. To create a new frame without a title bar use the Frame() constructor with no arguments. Frame f = new Frame(); More commonly you'll want to name the frame by passing a string that specifies the window's title to the constructor: Frame f = new Frame("My Window"); Frames inherit from java.awt.Container so you can add components to a frame. Unlike panels and applets, the default LayoutManager for a frame is BorderLayout, not FlowLayout. However you can change this using the frame's setLayout() method like this: f.setLayout(new FlowLayout()); Frames inherit from java.awt.Component so they have paint() and update() methods. If you want to draw in the frame and process events manually like you did in applets, just create a subclass of Frame and add listener objects to it. However most of the time you'll prefer to use components. To add a component to a frame call the frame's add() method just as you would call an applet's add() method. f.add(new Button("OK");

Since the default layout for a frame is BorderLayout, you should specify whether you want the component added to the North, South, East, West or Center. Here's how you'd add a centered label to the center of Frame f: f.add(BorderLayout.CENTER, new Label("This is a frame", Label.CENTER));

The size and position of any given frame is unpredictable unless you specify it. Specifying the size is easy. Just call the frame's setSize() method like this f.setSize(150,150);

This size does not include the title bar so you'll need to account for that separately. To determine the height of a Frame's title bar call its insets() method and look at the top member of the resulting java.awt.Insets object. That will be the height of the title bar. That is, int titleBarHeight = f.insets().top;

Moving the Frame to the proper place on the screen takes a little more effort. You move a Frame with the setLocation(int x, int y) method. However x and y are relative to the screen, not to the applet.

When a window is first created, it's invisible. Add components to the Frame while it's still invisible. The effect of Buttons, Labels and other widgets popping onto a layout in rapid succession while the window jumps around and changes size can be quite disconcerting. When you're done adding components, resizing and moving the Frame, make it visible by calling its show() method like so: f.show();

You can resize a frame to the exact size necessary for what it holds using the pack() method: f.pack()

Using the Frame Class to Implement Application Windows


The Frame class is a subclass of Window that encapsulates an application window. A Frame object is capable of containing a menu bar and displaying a title. The following coding shows how a Frame object is used to implement a simple window program.

CODING -- The FrameExample program. import java.awt.*; public class FrameExample extends Frame { public static void main(String args[]){ FrameExample win = new FrameExample(); } public FrameExample() { super("FrameExample"); pack(); resize(400,400); show(); } public void paint(Graphics g) { g.drawString("A Basic Window Program",100,100); } public boolean handleEvent(Event event) { if(event.id==Event.WINDOW_DESTROY){ System.exit(0); return true; }else return false; } }

OUTPUT

EXPLANATION After you create a Frame object within an application, you use the show() method to display the frame. The show() method is inherited from the Window class. Other methods used in the initial display of a Frame object are the pack() and resize() methods. The pack() method, like the show() method, is inherited from the Window class. It organizes the components contained in a Window object and determines the Window object's size. The resize() method is inherited from the Component class. It is used to resize a Window object to a particular dimension.

The main class of the program subclasses the Frame class and creates a single main() method like those used in console programs. The main() method uses the FrameExample() constructor to create a window for an application. The FrameExample() constructor uses the superclass constructor to set the title of the window to FrameExample. The pack() method is typically used to pack the components of the window, which allows Java to organize the component objects on the window. The resize() method is invoked to resize the window to 400 pixels by 400 pixels. Finally, the show() method is invoked to cause the window to be displayed. The paint() method is invoked by the runtime system to initially paint the contents of the application window and to repaint the window if it is moved, resized, or covered. The paint() method is passed an object of the Graphics class as a parameter. This object is used to update the window's display by drawing on its default canvas. The paint() method of FrameExample draws the text A Basic Window Program at the coordinates (100,100). The handleEvent() method usually provides the primary event handling for AWT components. A handleEvent() method is typically provided with a program's Frame subclass. The handleEvent() method of FrameExample looks for a

WINDOW_DESTROY event and shuts down the program using the exit() method of the System class. The Event class is covered in the section titled "Handling Events in Programs That Use Windows."

GRAPHICS
The Graphics class is part of the AWT. It's contained in java.awt.Graphics, and it's the basic class for everything you'll draw on-screen. Applets have associated Graphics instances, as do various components such as buttons. Drawing methods, such as drawLine, work on a Graphics instance. public void paint(Graphics g) { g.drawLine(10,10,20,20); } The Graphics class uses a standard computer coordinate system with the origin in the upper- left corner. All coordinate measurements in Java are done in pixels. The size of items, therefore, in absolute units such as inches or millimeters, differs on various machines due to differing pixels/inch values.

DRAWING SHAPES
Java's Graphics class includes methods for drawing many different types of shapes, everything from straight lines to polygons. A reference to a Graphics object is passed to the paint() method as its single argument. Because the Graphics class is part of the awt package, you have to include one of the following lines at the top of your applet's code to use the class: import java.awt.Graphics; import java.awt.*; The first line in the preceding imports only the Graphics class, whereas the second line imports all the classes included in the awt package.

The most commonly used drawing methods in the Graphics class. Drawing Methods of the Graphics Class. Method clearRect() copyArea() Description Erases a rectangular area of the canvas. Copies a rectangular area of the canvas to another area. drawArc() drawLine() drawOval() drawPolygon() drawRect() drawRoundRect() Draws a hollow arc. Draws a straight line. Draws a hollow oval. Draws a hollow polygon. Draws a hollow rectangle. Draws a hollow rectangle with rounded corners. drawString() fillArc() fillOval() fillPolygon() fillRect() fillRoundRect() Displays a text string. Draws a filled arc. Draws a filled oval. Draws a filled polygon. Draws a filled rectangle. Draws a filled rectangle with rounded corners. getColor() getFont() getFontMetrics() setColor() setFont() Retrieves the current drawing color. Retrieves the currently used font. Retrieves information about the current font. Sets the drawing color. Sets the font.

To draw a shape in an applet's display area, you only need to call the appropriate method and supply the arguments required by the method. These arguments are based on the coordinates at which you want to draw the shape. Example : The following code example draws a straight line from coordinate 5,10 to 20,30: g.drawLine(5, 10, 20, 30); The g in the preceding code line is the Graphics object passed to the paint() method. The drawLine() method takes four arguments, which are X,Y coordinate pairs that specify the starting and ending points of the line. TIP There may be times when you need to retrieve information about the system's currently set graphical attributes. Java's Graphics class supplies methods like getColor(), getFont(), and getFontMetrics() to enable you to obtain this information.

DRAWING LINES ,ARCS AND A POINT


Three methods for drawing lines currently are available in Java. The following coding shows a small applet that demonstrates how to draw straight lines, arcs, and a point.

CODING -- DRAWING STRAIGHT LINES, ARCS, AND A POINT.


import java.awt.*; import java.applet.Applet; public class drawpoint extends Applet{ public void paint(Graphics g)

{ int x_final, y_final; int i; //this draws a line g.drawLine(10,10,100,100); //this draws a point at 10,30 g.drawLine(10,30,10,30); //this draws an arc g.drawArc(50,50,30,30,0,180); //this draws a filled arc g.fillArc(50,100,20,40,90,90); } }

OUTPUT

A point, a line, an arc and a filled arc.

Descriptions for the three line-drawing methods.

drawLine(int x_start, int y_start, int x_end, int y_end)


This draws a line between two points.
x_start: Starting x position y_start: Starting y position x_end: Final x position y_end: Final y position

drawArc(int x, int y, int width, int height, int start_angle, int delta_angle)
This routine draws an arc, a segment of an ellipse, or a circle,

Parameters for drawArc and fillArc method.


x: y:

Upper-left corner of the rectangle that contains the ellipse the arc is from. Upper-left corner of the rectangle that contains the ellipse the arc is from. The width of the rectangle that contains the ellipse the arc is from. The height of the rectangle that contains the ellipse the arc is from. The angle at which the arc starts; 0 degrees is at the 3 o'clock position, and the

width: height:

start_angle:

value increases in the counterclockwise direction.

fillArc(int x, int y, int width, int height, int start_angle, int delta_angle)
This is the same as drawArc, except that the arc is filled with the current color. One of the key shortcomings with current Java drawing routines is that you can't specify a line width. All the drawing commands draw unit-width lines.

DRAWING A RECTANGLE
Most of the shape-drawing methods are as easy to use as the drawLine() method is. Suppose that you want to write an applet that draws a filled rounded rectangle inside a hollow rectangle. You'd then add calls to the Graphics class's fillRoundRect() and drawRect() to the applet's paint() method. Following Figure shows the applet running under Appletviewer.

This is RectApplet running under Appletviewer.

CODING -- RECTAPPLET.JAVA: Drawing Rectangles. import java.awt.*; import java.applet.*; public class RectApplet extends Applet { public void paint(Graphics g)

{ g.drawRect(35, 15, 125, 200); g.fillRoundRect(50, 30, 95, 170, 15, 15); } }

EXPLANATION( of RectApplet.java) In RectApplet's paint() method, you can see the method calls that produce the graphical display. The first line creates the outside rectangle. That method call looks like this: g.drawRect(35, 15, 125, 200); The drawRect() method's four arguments are the X,Y coordinates of the rectangle's upper-left corner and the width and height of the rectangle. The rounded filled rectangle is almost as easy to draw: g.fillRoundRect(50, 30, 95, 170, 15, 15); The fifth and sixth arguments are the size of the rectangle that represents the rounded corners. Think of this rectangle as being placed on each corner of the main rectangle and a curved line drawn between its corners, as shown in Figure

DRAWING OVALS
The call to drawOval() looks like this: g.drawOval(35, 50, 125, 180); This method, which draws ovals and circles, takes four arguments. These arguments are the X,Y coordinates, width, and height of a rectangle that can enclose the oval. The Following figure shows how the resultant oval relates to its enclosing rectangle.

An oval's coordinates are actually the coordinates of an enclosing rectangle. NOTE Most of the shape-drawing methods come in two versions, one that draws a hollow shape and one that draws a filled shape. The method that draws the filled shape has the same name as the one that draws the hollow shape, except you change the word draw in the name to fill. For example, because drawArc() draws a hollow arc, the method fillArc() draws a filled arc.

DRAWING POLYGONS
Polygons are simply many-sided shapes. For example, a triangle is a polygon (it is, in fact, the simplest polygon). Squares, rectangles, and hexagons are all polygons, as well. Because a polygon comprises many different lines, before you can draw a polygon in Java, you need to create arrays that contain the X,Y coordinates for each line in the polygon. ShapeApplet defines those arrays like this: int x[] = {35, 150, 60, 140, 60, 150, 35}; int y[] = {50, 80, 110, 140, 170, 200, 230}; int numPts = 7; The first array, called x[] in the preceding, is the X coordinates for each X,Y pair, and the second array, called y[], is the Y coordinates for each X,Y pair. By looking at the values defined in the arrays, you can see that the first line gets drawn from 35,50 to 150,80. Because all the lines in a polygon are connected, Java can continue drawing lines by using the previous ending point (in this case, 150,80) and the next coordinate pair, which is 60,110. Java will continue to work through the arrays until it uses all the given coordinates. The actual method call that draws the polygon looks like this: g.drawPolygon(x, y, numPts); The drawPolygon() method's three arguments are the array holding the X coordinates, the array holding the Y coordinates, and the number of points defined in the arrays. You can use a literal value for the third argument, but it's often handy to define a variable as shown in the example (numPts). Then, if you change the arrays, you can change the variable at the same time and not have to worry about correcting any method calls that use the arrays along with point count.

Figure shows the polygon drawn by the values given in the x[] and y[] arrays in the preceding. Looks more like a squiggly line than a polygon. That's because when you draw a hollow polygon, Java doesn't connect the starting and ending point

A hollow polygon is always missing one side. NOTE If you need more control over your polygons, Java includes a Polygon class from which you can create polygon objects from the coordinate arrays. The Polygon class includes handy methods that enable you to add points to a polygon, determine whether a point is inside the polygon, and retrieve the polygon's bounding rectangle. You create a
Polygon object

with a line like Polygon polygon = new Polygon(x, y, numPts).

The arguments for the class's constructor are the same as those for the
drawPolygon()

method. The Polygon class's public methods are addPoint(x, (which returns a Rectangle object), and inside() (which

y), getBoundingBox()

returns a boolean value).

WORKING WITH FONTS


The Font class encapsulates fonts in a system-independent manner by defining several system-independent fonts that are mapped to the fonts supported by the local operating and windowing system. This class also defines constants that allow a Font object to be displayed using a plain, bold, italic, or bold-italic style. The FontMetrics class encapsulates the size parameters of a Font object. It provides several methods that return the pixel width of characters and character strings, as well as methods that return the height, ascent, descent, and leading pixel length of a Font object. The ascent and descent values measure the number of pixels that a Font object ascends above and descends below its baseline. The leading of a Font object is the minimum distance between the ascent of one line of text and ascent of the following line of text. The height of a Font object is the sum of its ascent, descent, and leading. SYNTAX You can create instances of the Font class using this creator syntax: Font a_font = new Font(String name_of_font, int font_style, int font_size); The generally available fonts follow: Courier,Dialog,Helvetica,Symbol,TimesRoman Because the set of available fonts may change, you might want to use a variation of the applet shown to check for what fonts are available; this code works in applications as well.

CODING -- Checking for available fonts. import java.awt.*; import java.applet.Applet;

public class discover_fonts extends Applet { public void paint(Graphics g){ String FontList[]; int i; Font a_font; FontList = getToolkit().getFontList(); for(i=0;i<FontList.length;i++) { a_font = new Font(FontList[i],Font.BOLD,12); g.setFont(a_font); g.drawString("This is the " + FontList[i] + " Font",25, 15*(i + 1)); } } }

The applet just gets a list of strings containing the names of the available fonts. The last line is Symbol font. The style for all the fonts was set to bold by using the font constant Font.BOLD. You also can use Font.ITALIC and Font.PLAIN. You can combine styles by bitwise ORing them. This line produces a font that is both italic and bold, for example: Font a_font = new Font("Helvetica",(Font.BOLD | Font.ITALIC),12);

MEASURING FONTS, CENTERING TEXT


The FontMetrics class provides an easy way to find out how much space text drawn with a given instance of Font will be. Just in case you're not a typographic expert, the table provides some quick definitions of the key font measurement terms, illustrated in following figure.

Font terminology. Table -- FontMetrics terms. Height The height of the tallest character in a font. It's therefore the maximum vertical distance you need to reserve when drawing a string with the font. Baseline The bottom of all characters are positioned on this imaginary line. The descent part of a character, such as the bottom curl on a g, lies below this line. Ascent Measures the height of the character above the baseline. This can include the amount of whitespace recommended by the font designer. Descent Measures the height (or, more appropriately, depth) of the character below the baseline. This can include the amount of whitespace recommended by the font designer.

EXAMPLE PROGRAMS: (USING FontMetrics Class)

EXAMPLE 1 -- Accessing FontMetrics information. import java.awt.*; import java.applet.Applet; public class font_metrics extends Applet { public void paint(Graphics g){ Font a_font; FontMetrics a_font_metric; String the_message; int string_width, font_height,font_ascent, font_descent; int font_ascent_no_white, font_descent_no_white; int y; the_message = "Alien Space Monsters! ";
//Make a new font

a_font = new Font("Helvetica",Font.BOLD,16); g.setFont(a_font);


//get the metrics for the font

a_font_metric = g.getFontMetrics();
//get the width of the message

string_width= a_font_metric.stringWidth(the_message);
//get the height of the font

font_height = a_font_metric.getHeight();

//get the ascent of the font; this includes // whitespace recommended by the font designer

font_ascent = a_font_metric.getAscent();
//get the descent of the font; this includes // whitespace recommended by the font designer

font_descent = a_font_metric.getDescent();
//get the ascent without whitespace

font_ascent_no_white = a_font_metric.getMaxAscent();
//get the descent without whitespace

font_descent_no_white = a_font_metric.getMaxDescent();
//now show these values to the user

y = 10; g.drawString(the_message, 10,y); y += font_height + 1; g.drawString("Message width is " + string_width, 10,y); y += font_height + 1; g.drawString("Font height is " + font_height, 10,y); y += font_height + 1; g.drawString("Font ascent is " + font_ascent + " without white space it's " + font_ascent_no_white , 10,y); y += font_height + 1; g.drawString("Font descent is " + font_descent + " without white space it's " + font_descent_no_white , 10,y); } }

OUTPUT

Viewing FontMetrics information. This information is useful in a number of ways. First, notice how the tops of the letters in the first line in output is cut off. That's because when you specify the y coordinate for a string, you're specifying the location of the baseline-not the upper-left corner of the text that is being drawn. To figure out where to put the baseline, you just need to look at the value of the ascent. Instead of defining the first value of y as 10, just change it to this:
y = font_ascent + 2; //the extra 2 provides some whitespace //that the font otherwise lacks

The first line will now is completely visible, as shown in following figure :

Keeping your text in sight. EXAMPLE 2 - Centering text Another common use for FontMetrics data is to center text in an area. The code given below centers text in an area. CODING -- Centering text. public void draw_centered_text(Graphics g, String the_msg, int width, int height) { int x,y; FontMetrics fm; fm = g.getFontMetrics();
//find out how much free space there is on either side of the string by //subtracting the width of the string from the width of the window and //dividing by 2

x = (width - fm.stringWidth(the_msg))/2;
//find out how much free space there is above //and below the string's baseline

y = fm.getAscent() + (height - fm.getHeight())/2;


//draw the string so that the baseline is centered

g.drawString(the_msg,x,y); }

NOTE You can get the width and height of an applet's area by using the getSize method, which returns a Dimension value. The height() and width() methods of the Dimension class enable you to get the height and width values. OUTPUT

Centering text.

AWT CONTROLS (THE BASIC USER INTERFACE COMPONENTS)


The simplest form of awt component is the basic UI component. You can create and add these to your applet without needing to know anything about creating containers or panels-your applet, even before you start painting and drawing and handling events, is already an awt container. An applet is a container, you can put other awt components-such as UI components or other containers-into it. The basic UI components: labels, buttons, check boxes, choice menus, and text fields. The procedure for creating the component is First create the component Then add it to the panel that holds it, at which point it is displayed on the screen. To add a component to a panel (applet) use the add() method. Example: public void init() { Button b = new Button("OK"); add(b); } Note also that each of these components has an action associated with it-that is, something that component does when it's activated. Actions generally trigger events or other activities in your applet (they are often called callbacks in other window toolkits).

LABELS
The simplest form of UI component is the label, which is, effectively, a text string that you can use to label other UI components. Labels are not editable; they just label other components on the screen. The advantages that a label has over an ordinary text string (that you'd draw using
drawString()

in the paint() method) are

You don't have to redraw labels yourself. Labels are an awt element, and the awt keeps track of drawing them.

Labels follow the layout of the panel in which they're contained and can be aligned with other UI components.

A label is an un-editable text string that acts as a description for other awt components. To create a label, use one of the following constructors:

Label() creates an empty label, with its text aligned left. Label(String) creates a label with the given text string, also aligned left. Label(String, int) creates a label with the given text string and the given alignment. The available alignment numbers are stored in class variables in Label, making them easier to remember: Label.RIGHT, Label.LEFT, and Label.CENTER.

The label's font can be changed with the setFont() method, either called on the label itself to change the individual label, or on the enclosing component to change all the labels.

EXAMPLE PROGRAM A simple code to create a few labels in Helvetica Bold.

CODING import java.awt.*; public class LabelTest extends java.applet.Applet { public void init() { setFont(new Font ("Helvetica", Font.BOLD, 14)); setLayout(new GridLayout(3,1)); add(new Label("aligned left", Label.LEFT)); add(new Label("aligned center", Label.CENTER)); add(new Label("aligned right", Label.RIGHT)); } } OUTPUT

Three labels with various alignments NOTE This code uses the setLayout method to create a new layout manager.

When you have a Label object, you can use methods defined in the Label class to get and set the values of the text, as shown in Table : Table Showing Label methods. METHOD getText() setText(String) getAlignment() ACTION Returns a string containing this label's text Changes the text of this label Returns an integer representing the alignment of this label: 0 1 2 setAlignment(int) is Label.LEFT is Label.CENTER is Label.RIGHT

Changes the alignment of this label to the given integer-use the class variables listed in the getAlignment() method

BUTTONS
The second user interface component is the button. Buttons are simple UI components that trigger some action in your interface when they are pressed. For example, a calculator applet might have buttons for each number and operator, or a dialog box might have buttons for OK and Cancel. A button is a UI component that, when pressed (selected) with the mouse, triggers some action.

To create a button, use one of the following constructors:


Button() creates an empty button with no label. Button(String) creates a button with the given string as a label.

Once you have a Button object, you can get the value of the button's label by using the
getLabel()

method and set the label using the setLabel(String) method.

CODING For adding Four Buttons public class ButtonTest extends java.applet.Applet { public void init() { add(new Button("Rewind")); add(new Button("Play")); add(new Button("Fast Forward")); add(new Button("Stop")); } } OUTPUT

Four buttons in Netscape.

CHECK BOXES
Check boxes are user-interface components that have two states: on and off (or checked and unchecked, selected and unselected, true and false, and so on). Unlike buttons, check boxes usually don't trigger direct actions in a UI, but instead are used to indicate optional features of some other action. Check boxes can be used in two ways:

Nonexclusive: Given a series of check boxes, any of them can be selected. Exclusive: Given a series, only one check box can be selected at a time.

The latter kind of check boxes are called radio buttons or check box groups, and are described in the next section. Check boxes are UI components that can be selected or deselected (checked or unchecked) to provide options. Nonexclusive check boxes can be checked or unchecked independently of other check boxes. Exclusive check boxes, sometimes called radio buttons, exist in groups; only one in the group can be checked at one time. Nonexclusive check boxes can be created by using the Checkbox class. You can create a check box using one of the following constructors:
Checkbox()

creates an empty check box, unselected. creates a check box with the given string as a label. creates a check box that is either selected or

Checkbox(String)

Checkbox(String, null, boolean)

deselected based on whether the boolean argument is true or false, respectively. (The null is used as a placeholder for a group argument. Only radio buttons have groups, as you'll learn in the next section.)

EXAMPLE PROGRAM To show a few simple check boxes (only Underwear is selected) generated using the following code:

CODING import java.awt.*; public class CheckboxTest extends java.applet.Applet { public void init() { setLayout(new FlowLayout(FlowLayout.LEFT)); add(new Checkbox("Shoes")); add(new Checkbox("Socks")); add(new Checkbox("Pants")); add(new Checkbox("Underwear", null, true)); add(new Checkbox("Shirt")); } } OUTPUT

Five check boxes, one selected.

Check box methods. METHOD getLabel() ACTION Returns a string containing this check box's label setLabel(String) getState() Changes the text of the check box's label Returns true or false, based on whether the check box is selected setState(boolean) Changes the check box's state to selected (true) or unselected (false)

CHECKBOX GROUP (Radio Buttons)


Radio buttons have the same appearance as check boxes, but only one in a series can be selected at a time. To create a series of radio buttons, first create an instance of CheckboxGroup: CheckboxGroup cbg = new CheckboxGroup(); Then create and add the individual check boxes using the constructor with three arguments (the first is the label, the second is the group, and the third is whether that check box is selected). Note that because radio buttons, by definition, have only one in the group selected at a time, the last true to be added will be the one selected by default: add(new Checkbox("Yes", cbg, true); add(new Checkbox("No", cbg, false);

EXAMPLE

CODING import java.awt.*; public class CheckboxGroupTest extends java.applet.Applet { public void init() { setLayout(new FlowLayout(FlowLayout.LEFT)); CheckboxGroup cbg = new CheckboxGroup(); add(new Checkbox("Red", cbg, false)); add(new Checkbox("Blue", cbg, false)); add(new Checkbox("Yellow", cbg, false)); add(new Checkbox("Green", cbg, true)); add(new Checkbox("Orange", cbg, false)); add(new Checkbox("Purple", cbg, false)); } } OUTPUT

Six radio buttons (exclusive check boxes), one selected.

All the check box methods can be used with the check boxes in the group. In addition, you can use the getCheckboxGroup() and setCheckboxGroup() methods (defined in the Checkbox() class) to access and change the group of any given check box. Finally, the getCurrent() and setCurrent(Checkbox) methods, defined in

CheckboxGroup, can be used to get or set the currently selected check box.

CHOICE MENUS
The choice menu is a more complex UI component than labels, buttons, or check boxes. Choice menus are pop-up (or pull-down) menus from which you can select an item. The menu then displays that choice on the screen. The function of a choice menu is the same across platforms, but its actual appearance may vary from platform to platform. Note that choice menus can have only one item selected at a time. If you want to be able to choose multiple items from the menu, use a scrolling list instead . Choice menus are pop-up menus of items from which you can choose one item. To create a choice menu, create an instance of the Choice class and then use the addItem() method to add individual items to it in the order in which they should appear. Finally, add the entire choice menu to the panel in the usual way. A simple program that builds a choice menu of fruits; CODING import java.awt.*; public class ChoiceTest extends java.applet.Applet { public void init() { Choice c = new Choice(); c.addItem("Apples"); c.addItem("Oranges");

c.addItem("Strawberries"); c.addItem("Blueberries"); c.addItem("Bananas"); add(c); } } OUTPUT

A choice menu. Even after your choice menu has been added to a panel, you can continue to add items to that menu with the addItem() method. Other Choice menu methods. METHOD getItem(int) ACTION Returns the string item at the given position (items inside a choice begin at 0, just like arrays) countItems() getSelectedIndex() Returns the number of items in the menu Returns the index position of the item that's selected getSelectedItem() Returns the currently selected item as a

string select(int) select(String) Selects the item at the given position Selects the item with the given string

TEXT FIELDS
Unlike the UI components up to this point, which only enable you to select among several options to perform an action, text fields allow you to enter and edit text. Text fields are generally only a single line and do not have scrollbars; text areas Text fields are different from labels in that they can be edited; labels are good for just displaying text, text fields for getting text input from the user. Text fields provide an area where you can enter and edit a single line of text. To create a text field, use one of the following constructors:

TextField() creates an empty TextField that is 0 characters wide (it will be resized by the current layout manager).

TextField(int) creates an empty text field. The integer argument indicates the minimum number of characters to display.

TextField(String) creates a text field initialized with the given string. The field will be automatically resized by the current layout manager.

TextField(String, int) creates a text field some number of characters wide (the integer argument) containing the given string. If the string is longer than the width, you can select and drag portions of the text within the field, and the box will scroll left or right.

For example, the following line creates a text field 30 characters wide with the string
"Enter Your Name"

as its initial contents:

TextField tf = new TextField("Enter Your Name", 30); add(tf); You can also create a text field that obscures the characters typed into it-for example, for password fields. To do this, first create the text field itself; then use the setEchoCharacter() method to set the character that is echoed on the screen. Example Coding: TextField tf = new TextField(30); add(new Label("Enter your Name")); add(new TextField("your name here", 45)); add(new Label("Enter your phone number")); add(new TextField(12)); add(new Label("Enter your password")); TextField t = new TextField(20); t.setEchoCharacter('*'); add(t);

OUTPUT Shows three text boxes (and labels) that were created using the above code:

Three text fields to allow input from the user.

Text fields inherit from the class TextComponent and have a whole suite of methods both inherited from that class and defined in their own class that may be useful to you in your Java programs. Text field methods. METHOD getText() ACTION Returns the text this text field contains (as a string) setText(String) getColumns() select(int, int) Puts the given text string into the field Returns the width of this text field Selects the text between the two integer positions (positions start from 0) selectAll() isEditable() Selects all the text in the field Returns true or false based on whether the text is editable setEditable(boolean)
true

(the default) enables text to be

edited; false freezes the text getEchoChar() Returns the character used for masking input echoCharIsSet() Returns true or false based on whether the field has a masking character NOTE The descriptions of the getEchoChar() and echoCharIsSet() methods refer to masking user input. User input masking is a technique of limiting user input to a specific type, such as a number. Other types of user input masking include dates and phone numbers, where there are a specific number of numeric digits arranged in a constant format.

LAYOUT MANAGERS
Basics of Layout Managers
Java technology uses Layout Managers to define the location and size of Graphical User Interface components. Java technology does not encourage programmers to use absolute location and size of components. Java technology instead places components based on specified Layout Manager. A Layout Manager implements a layout policy that defines constraints between components in a container. The actual appearance of the awt components on the screen is usually determined by two things: 1. How those components are added to the panel that holds them (either the order or through arguments to add()). 2. The layout manager that panel is currently using to lay out the screen. The layout manager determines how portions of the screen will be sectioned and how components within that panel will be placed. The layout manager determines how awt components are dynamically arranged on the screen. Each panel on the screen can have its own layout manager. By nesting panels within panels, and using the appropriate layout manager for each one, you can often arrange your UI to group and arrange components in a way that is functionally useful and that looks good on a variety of platforms and windowing systems.

TYPES OF LAYOUT MANAGERS The awt provides five basic layout managers: FlowLayout, GridLayout,

BorderLayout, CardLayout, and GridBagLayout.

To create a layout manager for a given panel, create an instance of that layout manager and then use the setLayout() method for that panel. This example sets the layout manager of the entire enclosing applet panel: public void init() { setLayout(new FlowLayout()); } Setting the default layout manager, like creating user-interface components, is best done during the applet's initialization, which is why it's included here. After the layout manager is set, you can start adding components to the panel. The order in which components are added or the arguments you use to add those components is often significant, depending on which layout manager is currently active. Read on for information about the specific layout managers and how they present components within the panel to which they apply.

NO LAYOUT MANAGER
Although most containers come with a preset FlowLayout Manager, you can tell the AWT to use absolute positions with the following line of code: setLayout(null); This eliminates the default Layout Manager, or any other one that the container had been using, enabling you to position components by using absolute coordinates. The following applet uses absolute coordinates and the resize and reshape methods from the Component class to position and size a label and a text field. If you don't use resize or reshape, you won't see the components. This approach to layouts can run into problems when the size of a font varies between platforms. You can use the FontMetrics class to figure out the size of a font relative to some standard size and then scale your absolute coordinates, but it's always easier to implement a custom Layout Manager.

CODING -- Positioning and sizing a label and text field. import java.awt.*; import java.applet.Applet; public class no_layout extends Applet{ public void init(){ Label a_label; TextField a_textfield; setLayout(null); a_label = new Label("A label"); add(a_label);
//change the size of the Label

a_label.resize(40,50); a_textfield = new TextField(20); add(a_textfield);


//set the size and position of the TextField

a_textfield.reshape(20,40,140,10); } } OUTPUT

THE FLOWLAYOUT CLASS


The FlowLayout class is the most basic of layouts. Using flow layout, components are added to the panel one at a time, row by row. If a component doesn't fit onto a row, it's wrapped onto the next row. The flow layout also has an alignment, which determines the alignment of each row. By default, each row is centered. Flow layout arranges components from left to right in rows. The rows are aligned left, right, or centered. To create a basic flow layout with a centered alignment, use the following line of code in your panel's initialization (because this is the default pane layout, you don't need to include this line if that is your intent): setLayout(new FlowLayout()); With the layout set, the order in which you add elements to the layout determines their position. The following code creates a simple row of six buttons in a centered flow layout: CODING FLOW LAYOUT import java.awt.*; public class FlowLayoutTest extends java.applet.Applet { public void init() { setLayout(new FlowLayout()); add(new Button("One")); add(new Button("Two")); add(new Button("Three")); add(new Button("Four")); add(new Button("Five")); add(new Button("Six")); } }

OUTPUT

Six buttons, arranged using a flow layout manager. To create a flow layout with an alignment other than centered, add the FlowLayout.RIGHT or FlowLayout.LEFT class variable as an argument: setLayout(new FlowLayout(FlowLayout.LEFT)); You can also set horizontal and vertical gap values by using flow layouts. The gap is the number of pixels between components in a panel; by default, the horizontal and vertical gap values are three pixels, which can be very close indeed. Horizontal gap spreads out components to the left and to the right; vertical gap spreads them to the top and bottom of each component. Add integer arguments to the flow layout constructor to increase the gap. The Following figure shows the result of adding a gap of 30 points in the horizontal and 10 in the vertical directions with following line of code:

setLayout(new FlowLayout(FlowLayout.LEFT, 30, 10));

Flow layout with a gap of 10 points.

GRID LAYOUTS
Grid layouts offer more control over the placement of components inside a panel. Using a grid layout, you portion off the display area of the panel into rows and columns. Each component you then add to the panel is placed in a cell of the grid, starting from the top row and progressing through each row from left to right (here's where the order of calls to the add() method are very relevant to how the screen is laid out). To create a grid layout, indicate the number of rows and columns you want the grid to have when you create a new instance of the GridLayout class. The following code produces grid layout with three rows and two columns CODING GRID LAYOUT import java.awt.*; public class GridLayoutTest extends java.applet.Applet { public void init() { setLayout(new GridLayout(3,2); add(new Button("One")); add(new Button("Two"));

add(new Button("Three")); add(new Button("Four")); add(new Button("Five")); add(new Button("Six")); } }

OUTPUT

Six buttons displayed using a grid layout of three rows and two columns. Grid layouts can also have a horizontal and vertical gap between components. To create gaps, add those pixel values: setLayout(new GridLayout(3, 3, 10, 30));

BORDER LAYOUTS
Border layouts behave differently from flow and grid layouts. When you add a component to a panel that uses a border layout, you indicate its placement as a geographic direction: north, south, east, west, or center. The components around all the edges are laid out with as much size as they need; the component in the center, if any, gets any space left over.

Components go in a border layout. To use a border layout, you create it as you do the other layouts; then you add the individual components with a special add() method that has two arguments. The first argument is a string indicating the position of the component within the layout, and the second is the component to add: add("North", new TextField("Title", 50)); You can also use this form of add() for the other layout managers; the string argument will just be ignored if it's not needed.

Here's the code to generate the border layout shown in above figure: CODING BORDER LAYOUT import java.awt.*; public class BorderLayoutTest extends java.applet.Applet { public void init() { setLayout(new BorderLayout()); add("North", new Button("One")); add("East", new Button("Two")); add("South", new Button("Three")); add("West", new Button("Four")); add("Center", new Button("Five")); add(new Button("Six")); } }

Border layouts can also have horizontal and vertical gaps. Note that the north and south components extend all the way to the edge of the panel, so the gap will result in less vertical space for the east, right, and center components. To add gaps to a border layout, include those pixel values in the constructor as with the other layout managers: setLayout(new BorderLayout(10, 10));

CARD LAYOUTS
Card layouts behave much differently from the other layouts. When you add components to one of the other layout managers, all those components appear on the screen at once. Card layouts are used to produce slide shows of components, one at a time. When you create a card layout, the components you add to the outer panel will be other container components-usually other panels. You can then use different layouts for those individual cards so that each screen has its own look. Cards, in a card layout, are different panels added one at a time and displayed one at a time. If you think of a card file, you'll get the idea; only one card can be displayed at once, but you can switch between cards. When you add each card to the panel, you can give it a name. Then, to flip between the container cards, you can use methods defined in the CardLayout class to move to a named card, move forward or back, or move to the first card or to the last card. Typically you'll have a set of buttons that call these methods to make navigating the card layout easier.

Here's a simple snippet of code that creates a card layout containing three cards: setLayout(new CardLayout()); //add the cards Panel one = new Panel() add("first", one); Panel two = new Panel() add("second", two); Panel three = new Panel() add("third", three); // move around show(this, "second"); //go to the card named "second" show(this, "third"); previous(this); first(this); //go to the card named "third" //go back to the second card // got to the first card

INSETS
Horizontal and vertical gap, created when you create a new layout manager (using ipadx and ipady in grid bag layouts), are used to determine the amount of space between components in a panel. Insets, however, are used to determine the amount of space around the panel itself. The Insets class includes values for the top, bottom, left, and right insets, which are then used when the panel itself is drawn. Insets determine the amount of space between the edges of a panel and that panel's components.

To include an inset, override the insets() method in your class (your Applet class or other class that serves as a panel). Inside the insets() method, create a new Insets object, where the constructor to the Insets class takes four integer values representing the insets on the top, left, bottom, and right of the panel. The insets() method should then return that Insets object. Here's some code to add insets for a grid layout, 10 to the top and bottom, and 30 to the left and right.

A panel with insets of 10 pixels on the top and bottom and 30 pixels to the left and right. public Insets insets() { return new Insets(10, 30, 10, 30); } The arguments to the Insets constructor provide pixel insets for the top, bottom, left, and right edges of the panel, respectively. This particular example provides an inset of 10 pixels on all four sides of the panel.

USING MENUS AND MENU BARS

The MenuBar class provides an implementation of the menu bar commonly attached to stand-alone applications. It is a subclass of the MenuComponent class, which provides a common set of methods for all menu-related classes. You attach a MenuBar object to a Frame object using the setMenuBar() method of the Frame class. A MenuBar object contains one or more Menu objects that implement pull-down menus. The Menu class provides methods for adding MenuItem objects and separators to the pull-down menu implemented by a Menu object.

It also provides methods for accessing the MenuItem objects contained in a Menu object. Because the Menu class is a subclass of the MenuItem class, a Menu object can contain another Menu object, thus allowing multiple levels of cascading menus to be created.

The program shown below illustrates this concept. CODING -- The MenuExample program. import java.awt.*; public class MenuExample extends Frame { String menuSelection = "Select a menu item."; public static void main(String args[]){ MenuExample win = new MenuExample(); } public MenuExample() { super("MenuExample"); pack(); resize(400,400); addMenus();

show(); } void addMenus() { MenuBar menubar = new MenuBar(); Menu file = new Menu("File"); Menu edit = new Menu("Edit"); Menu view = new Menu("View"); file.add("Open"); file.add("Save"); file.add("Close"); file.add("Quit"); edit.add("Copy"); edit.add("Cut"); edit.add("Paste"); view.add("Zoom"); menubar.add(file); menubar.add(edit); menubar.add(view); setMenuBar(menubar); } public void paint(Graphics g) { g.drawString(menuSelection,100,100); } public boolean handleEvent(Event event) { if(event.id==Event.WINDOW_DESTROY){ System.exit(0); return true; }else if(event.id == Event.ACTION_EVENT && event.target instanceof MenuItem){ if("Quit".equals(event.arg)){ System.exit(0); return true;

}else{ menuSelection = "You selected +event.arg.toString()+"."; repaint(); return true; } }else return false; } }

EXPLANATION The MenuItem class is a subclass of the MenuComponent class that is used to implement an item contained in a pull-down menu. It provides methods for enabling and disabling (graying out) the label associated with a MenuItem object and for setting and retrieving the label. The MenuItem class has two subclasses-Menu and

CheckboxMenuItem. You have already been introduced to the Menu class; the CheckboxMenuItem class implements a menu item that can be checked or unchecked and provides methods that can be used to set and retrieve its checked status. To learn more about check boxes, see the section "Check Boxes and Radio Buttons." The MenuComponent class is the superclass of these menu classes. Its methods are used to perform general menu-related operations, such as those used to create menu items. The MenuContainer interface defines those methods that must be implemented by any class that contains a menu-related object. The MenuContainer interface is implemented by the Frame, Menu, and MenuBar classes. The MenuExample program invokes the addMenus() method in the MenuExample() constructor to set up the window's menus. Notice that the menuSelection variable is a String object and is declared as a field variable of the MenuExample class.

The addMenus() method creates a MenuBar object and some Menu objects and then adds menu items to the Menu objects. The Menu objects are then added to the MenuBar object, and the MenuBar object is set on the application window using the setMenuBar() method. The paint() method is overridden to draw the menu item selected by the user on the window's default canvas. Note that you generally don't call the paint() method directly. The paint() method is invoked automatically when you use these methods: show(), repaint(), or update(). The handleEvent() method of the FrameExample program is expanded to check for an ACTION_EVENT object with a MenuItem as its target in order to handle the action of a user selecting an item from a menu. It updates the menuSelection object to identify the menu item selected by the user. The repaint() method is used to cause the window to be redrawn, which, as discussed, invokes the paint() method for you. Figure shows the window initially displayed by the MenuExample program.

The MenuExample program's initial display.

DIALOG BOXES
Implementing Dialog Boxes with the Dialog Class
The Dialog class, like the Frame class, is a subclass of the Window class. Whereas the Frame class is used to implement a main application window, the Dialog class is used to implement dialog boxes that pop up to present information and interact with the user of a window program or applet. Two types of Dialog objects can be created. A modal dialog box is a Dialog object that must be acted on and closed before a user is able to access other application windows. A non-modal dialog box does not have this restriction. The program shown below illustrates the use of the Dialog class. CODING -The DialogExample program.

import java.awt.*; public class DialogExample extends Frame { Dialog dialog; public static void main(String args[]){ DialogExample win = new DialogExample(); } public DialogExample() { super("DialogExample"); pack(); resize(400,400); addMenus(); createDialog(); show(); } void addMenus() { MenuBar menubar = new MenuBar(); Menu file = new Menu("File");

Menu dialog = new Menu("Dialog"); file.add("Quit"); dialog.add("Show"); dialog.add("Hide"); menubar.add(file); menubar.add(dialog); setMenuBar(menubar); } void createDialog() { dialog = new Dialog(this,"Dialog Box",false); dialog.resize(200,200); } public boolean handleEvent(Event event) { if(event.id==Event.WINDOW_DESTROY){ System.exit(0); return true; }else if(event.id == Event.ACTION_EVENT && event.target instanceof MenuItem){ if("Quit".equals(event.arg)){ System.exit(0); return true; }else if("Show".equals(event.arg)){ dialog.show(); return true; }else{ dialog.hide(); return true; } }else return false; } }

OUTPUT

The DialogExample porgram's initial display. EXPLANATION The DialogExample program creates the dialog variable to refer to a dialog box that it creates and displays. The createDialog() method is invoked from the DialogExample constructor to create this dialog box. The addMenus() method has been updated to support menu items for showing and hiding the dialog box. The createDialog() method creates a non-modal dialog box and resizes it to a 200 pixel x 200 pixel size. The dialog box is not displayed until the Show menu item is selected and handled by the handleEvent() method. The handleEvent() method handles the Show menu item by causing the dialog box to be displayed via the show() method of the Window class. It handles the Hide menu item by invoking the hide() method of the Component class.

NOTE The show() method of the Window class overrides the show() method of the Component class and is used to display Window objects. Unlike the show() method of the Component class, the show() method of the Window class does more than merely display the window; it will also bring the window to the front if the window is already visible.

Using the FileDialog Class to Access the Local File System


The FileDialog class is a subclass of the Dialog class and is used to provide the capability to select a file from a directory listing. The FileDialog class provides the capability to use separate dialog boxes for loading and saving files. The program shown below illustrates the use of the FileDialog class. CODING -- The FileDialogExample program. import java.awt.*; public class FileDialogExample extends Frame { FileDialog dialog; public static void main(String args[]){ FileDialogExample win = new FileDialogExample(); } public FileDialogExample() { super("FileDialogExample"); pack(); resize(400,400); addMenus(); createDialog(); show();

} void addMenus() { MenuBar menubar = new MenuBar(); Menu file = new Menu("File"); Menu dialog = new Menu("Dialog"); file.add("Quit"); dialog.add("Show"); menubar.add(file); menubar.add(dialog); setMenuBar(menubar); } void createDialog() { dialog = new FileDialog(this,"File Dialog Box"); } public boolean handleEvent(Event event) { if(event.id==Event.WINDOW_DESTROY){ System.exit(0); return true; }else if(event.id == Event.ACTION_EVENT && event.target instanceof MenuItem){ if("Quit".equals(event.arg)){ System.exit(0); return true; }else if("Show".equals(event.arg)){ dialog.show(); return true; }else{ return false; } }else return false; } }

OUTPUT

The FileDialogExample program's initial display. The FileDialogExample program is very similar to the DialogExample program except that instead of creating and displaying a Dialog object, it displays a FileDialog object. Notice that the Hide menu item has been removed. This is because the File dialog box is modal and cannot be hidden after it is displayed. The createDialog() method creates the FileDialog object and titles it with the text File Dialog Box

Você também pode gostar