GUI in Java and overview of AWT and Swing APIs

The GUI (Graphical User Interface) in java can be done with AWT and also with Swing APIs. The major difference is that AWT depends on the Operating System classes for the components whereas Swing is 100% pure java components. This would mean that any component developed using Swing would look exactly the same in all operating systems, whereas AWT components tend to look little bit different in different operating systems. We will initially focus on the AWT components and later on the specific classes required for the TYBSc exams. The Swing components also have most of the AWT components with J added to it. For example Button in AWT would be JButton in Swing. The Java Abstract Windowing Toolkit (AWT) provides numerous classes that support window program development. These classes are used to create and organize windows, implement GUI components, handle events, draw text and graphics, perform image processing, and obtain access to the native Windows implementation. The basic idea behind the AWT is that a java window is a set of nested components starting from the outermost window all the way down to the smallest User Interface component. The AWT classes are contained in the java.awt package. It is one of the java’s largest packages. The AWT provides the basic GUI components that are used in java applets and applications. The AWT provides a machine-independent interface for applications. The AWT classes provide the following: a) A fell set of UI widgets and other components, including windows, menus, buttons, checkboxes etc. Support for UI containers, which can contain other embedded containers and widgets. Provision of Layout Managers whose duty is to handle the laying out of components on Containers. An event system for managing system and user events between and among parts of the AWT




The Component class is the super class of the set of AWT classes that implement graphical user interface controls. The Component class provides a common set of methods that are used by all these subclasses. These methods include methods for handling events and working with images, fonts, and colors. Java Components are implemented by the many subclasses of the java.awt.Component and java.awt.MenuComponent super class. The general way to categories them is to divide them into the following categories: a) b) c) Visual Components Container Components Menu Components

The fundamental visual controls in java are: 1. 2. 3. 4. 5. 6. 7. 8. Label – A simple label Button – A simple push button Checkbox – A combination of check box and radio (option) button Choice – A drop down list control List – A list box Scroll bar – Horizontal and Vertical Scroll bar Text Field – A single line text entry field Text Area – A multiple line text entry field

The fundamental Container Components in java are: 1) 2) 3) 4) Frame Window Applet Panel

The fundamental Menu Components are: 1) 2) 3) 4) MenuBar Menu MenuItem CheckboxMenuItem

The superclass of all Non-Menu items in java is the Component class and for all Menu Items the superclass is the MenuComponent class. JFC is short for Java Foundation Classes, which encompass a group of features to help people build graphical user interfaces (GUIs). The JFC was first announced at the 1997 JavaOne developer conference and is defined as containing the following features: The Swing Components Include everything from buttons to split panes to tables. Pluggable Look and Feel Support Gives any program that uses Swing components a choice of looks and feels. For example, the same program can use either the Java look and feel or the Windows look and feel. We expect many more look-and-feel packages -- including some that use sound instead of a visual "look" -to become available from various sources. Accessibility API Enables assistive technologies such as screen readers and Braille displays to get information from the user interface. Java 2D API (Java 2 Platform only) Enables developers to easily incorporate high-quality 2D graphics, text, and images in applications and in applets.

Drag and Drop Support (Java 2 Platform only) Provides the ability to drag and drop between a Java application and a native application. The first three JFC features were implemented without any native code, relying only on the APIs defined in JDK. As a result, they could and did become available as an extension to JDK 1.1. This extension was released as JFC 1.1, which is sometimes called "the Swing release." The API in JFC 1.1 is often called "the Swing API." Note: "Swing" was the codename of the project that developed the new components. Although it's an unofficial name, it's frequently used to refer to the new components and related API. It's immortalized in the package names for the Swing API, which begin with javax.swing.

Difference between AWT and Swing Components

The biggest difference between the AWT components and Swing components is that the Swing components are implemented with absolutely no native code. Since Swing components aren't restricted to the least common denominator -- the features that are present on every platform -they can have more functionality than AWT components. Because the Swing components have no native code, they can be shipped as an add-on to JDK 1.1, in addition to being part of the Java 2 Platform. Even the simplest Swing components have capabilities far beyond what the AWT components offer: 1. Swing buttons and labels can display images instead of, or in addition to, text. 2. You can easily add or change the borders drawn around most Swing components. For example, it's easy to put a box around the outside of a container or label. 3. You can easily change the behavior or appearance of a Swing component by either invoking methods on it or creating a subclass of it. 4. Swing components don't have to be rectangular. Buttons, for example, can be round. 5. Assistive technologies such as screen readers can easily get information from Swing components. For example, a tool can easily get the text that's displayed on a button or label. Swing lets you specify which look and feel your program's GUI uses. By contrast, AWT components always have the look and feel of the native platform. If you're used to using AWT components, you need to be aware of a few gotchas when using Swing components: 1. Programs should not, as a rule, use "heavyweight" components alongside Swing components. Heavyweight components include all the ready-to-use AWT components (such as Menu and ScrollPane) and all components that inherit from the AWT Canvas and Panel classes. This restriction exists because when Swing components (and all other "lightweight" components) overlap with heavyweight components, the heavyweight component is always painted on top. For more information, see Mixing Heavy and Light Components, an article in The Swing Connection.

2. Swing components aren't thread safe. If you modify a visible Swing component -invoking its setText method, for example -- from anywhere but an event handler, then you need to take special steps to make the modification execute on the event-dispatching thread. This isn't an issue for many Swing programs, since component-modifying code is typically in event handlers.

3. The containment hierarchy for any window or applet that contains Swing components must have a Swing top-level container at the root of the hierarchy. For example, a main window should be implemented as a JFrame instance rather than as a Frame instance.

4. You don't add components directly to a top-level container such as a JFrame. Instead, you add components to a container (called the content pane) that is itself contained by the JFrame.

Container Classes

The Container class is a subclass of the Component class that is used to define components that have the capability to contain other components. It provides methods for adding, retrieving, displaying, counting, and removing the components that it contains. The Container class also provides methods for working with layouts. The layout classes control the layout of components within a container. The Container class has two major subclasses: Window and Panel. Window provides a common super class for application main windows (Frame objects) and Dialog windows. The Panel class is a generic container that can be displayed within a window. It is sub classed by the java.applet.Applet class as the base class for all Java applets. The containers contain individual components inside them. The two important things done with the container is establishing the container’s layout manager and adding components to the container. Container is the abstract subclass of component, which allows other components to be nested inside it. These components can also be containers allowing other components to be nested inside it. 1. Window – It is a freestanding native window on the display. Window has Frame and Dialog as its subclasses 2. Frame – A frame is a window with a title and resizing corners. 3. Dialog – A Dialog does not have a menu bar. Although u can move it, you cannot resize it. 4. Panel – It is contained inside another container of inside a web browser’s window. Panel identifies a rectangular area into which you must place other components. You must place Panel into a Window or subclass of window to be displayed.

Incase you are not using the default layout managers associated with each container, we must ourselves place the components using the 3 methods – setLocation (), setSize () and setBounds (). The layout manager can override your decision. If you must control the size or position of components in such a way that cannot be done using the standard layout managers, you can disable the layout manager by issuing the following method call in your container Each Container has a default Layout Manager and to override that default layout manager, we use the method setLayout (new xxxLayout) where xxx is the name of the Layout which we want to set the container to. Incase we do not want to use the Layout Manger at all then we should use the method setLayout(null) and then it is the duty of the programmer to manually place the components. Every container is also a Component. In addition to the above methods, the class Component methods are also available for Container. The most common methods in the Component classes are: 1. 2. 3. 4. 5. 6. 7. 8. 9. setBounds setSize setEnabled setBackground getBackground isEnabled isVisible getLocation setLocation Changes control shape and location Changes control size Sets control to active or inactive Sets background color Gets background color Returns boolean indicating whether currently enables Returns boolean indicating whether control is visible Returns the x and y location Moves the control to a new location Asks system to give focus to control Sets Background Color Sets Foreground Color Sets font to font , style and size Returns the current size of control

10. requestFocus 11. getBackground 12. getForeground 13. setFont 14. getSize

The methods of the class Container are: Sr. No 1 Method Component add (Component c) Description Adds the specified component to the end of this container Adds the specified component to this container at the given position. Here the number would be –1 to insert at the end Gets the number of components in the container.


Component add (Component c, int pos)


int getComponentCount ()

5 6 7 8 9

Component getComponent (int n) LayoutManager getLayout () void remove (Component c) void removeAll () void setLayout (LayoutManager m)

Gets the specified Component Gets the container’s LayoutManager Remove the specified Component Removes all Components Re-Sets the Container’s LayoutManager

Frame Inherits from the container and adds components with the add() method. By Default, the Frame is invisible and hence always we have to use the method setVisible(true). We also have to call the method setSize(int width, int height) on the Frame always to set the Size of the Frame. Has Border Layout as the default layout manager



Code import java.awt.*; class Test101 extends Frame { public Test101(String s) { super(s); } public static void main(String args[]) { Test101 f = new Test101("My New Frame"); f.setSize(500,500); f.setBackground(; f.setVisible(true); } } Output - The above program creates a frame with size of 500 width by 500 height and with background color of blue. IMP: You will have to set visible to true in the case of Frame as by default it is set to invisible. You can either use setSize() or pack() (Which is a method of the Window class). The setSize() method gives the Frame a size as mentioned in the parameter, whereas the pack () method automatically arranges the component after giving 5 pixel space on all the sides. Hence the size of the Frame would depend on the number of components inside the Frame. Call the hide () to remove a frame from the screen.


Call dispose () method when the frame is no longer needed so that it can release its window system resources for reuse. The constructors for frame are: Constructs a frame Constructs a frame with appropriate title.


Frame () Frame (String title)

Code (Example of setSize() and pack() methods) import java.awt.*; class Test101A extends Frame { public Test101A(String s) { super(s); } public static void main(String arg[]) { Test101A fr = new Test101A("My New Frame"); fr.setLayout(new FlowLayout()); Button b = new Button("One"); Button c = new Button("Two"); fr.add(b); fr.add(c); fr.setSize(500,500); fr.setBackground(; fr.setVisible(true); fr.validate(); fr.repaint(); } } Output We are adding the method setLayout because the default layout manager of Frame is BorderLayout and only one component can be located at one position in that layout. The output would show a frame of the size of 500 by 500 and two buttons in the center. Incase we use the pack method instead of the setSize method, the revised code would look like Code import java.awt.*; class Test101B extends Frame { public Test101B(String s) { super(s); } public static void main(String arg[])

{ Test101B fr = new Test101B("My New Frame"); fr.setLayout(new FlowLayout()); Button b = new Button("One"); Button c = new Button("Two"); fr.add(b); fr.add(c); fr.pack(); fr.setBackground(; fr.setVisible(true); fr.validate(); fr.repaint(); } } Output We would see that only the buttons have been shows and 5 pixels are left on each side of the Frame. Whenever we are using the pack method, the Frame would take the preferred size of the components and lay them out and then add 5 pixels to the side of the Frame Component. Panel Panel is a container that does not have its own window. It is contained within some other container. The Panel class is a subclass of Container that provides a rectangular container for other GUI components. This technique is perfect for groups of controls like radio buttons or checkboxes, because it keeps the group of controls together. Panel can also have another Panel inside it. Applet is a subclass of Panel and thus Applets are displayed in a Panel that is contained within a web browser or applet viewer. The default LayoutManager for a Panel is FlowLayout. To construct a Panel you can use the following constructors: Creates a new Panel Creates a Panel with the specified LayoutManager




Panel () Panel ( LayoutManager layout) -


Panels allows sub-panels to have their own layout managers Adds components with the add () method.

Code import java.awt.*; class Test102 extends Frame { public Test102 (String s) { super(s);

} public static void main(String arg[]) { Test102 fr = new Test102 ("Panel inside a Frame"); Panel pan = new Panel(); fr. setSize(200,200); fr. setBackground(; fr. setLayout(null); pan.setSize(100,100); pan.setBackground(Color.yellow); fr.add(pan); fr.setVisible(true); } } Output: The output would be a frame with size of 200 by 200 with color as blue and a panel of 100 by 100 with a color of yellow. Applet A Applet is a java class file embedded in an HTML file which is executed when the html is loaded in the browser. The default layout of the Applet is FlowLayout. Code import java.awt.*; class Test101B extends Frame { public Test101B(String s) { super(s); } public static void main(String arg[]) { Test101B fr = new Test101B("My New Frame"); fr.setLayout(new FlowLayout()); Button b = new Button("One"); Button c = new Button("Two"); fr.add(b); fr.add(c); fr.pack(); fr.setBackground(; fr.setVisible(true); fr.validate(); fr.repaint(); } } HTML File

<applet code = Applet1.class height = 400 width = 400> </applet> Output For any applet code to be executed, we should embed the .class file in the HTML file as we have done in the above html file and then open this html file in the browser. The applet tag in the html file takes 3 mandatory parameters and they are:-a) b) c) code - Which is the class name of the class to be opened width - The width of the applet window. height - The height of the applet window

Window Window is the superclass of Frame and has BorderLayout as the default Layout. The difference between a Window and a Frame is that Window does not have a title bar and have no re-sizing corners and hence it would not be possible to change the Window once created. Window has method of pack () and show() which we have discussed earlier Code import java.awt.*; class Test103 { public static void main(String[] args) { Frame f = new Frame("My Frame"); f.setBackground(; f.setSize(400,400); f.setVisible(true); Window w = new Window(f); w.setBackground(; w.setSize(200,200); w.setVisible(true); } } Window cannot stand on its own and require Frame as its parent.

Layout Managers

The duty of the Layout Manager is to layout the component automatically once the container is resized. Each of the containers has a default layout manager and we can change them with the use of the setLayout(new LayoutManager) method.

Incase we set the layout manager to null, then we have to manually reposition the components using the methods setLayout(), setSize() and setBounds() methods. Every component has a preferred size (default size) and some of the Layout Managers fully honors and other does not honor the preferred size of the components. This would be discussed at the end of this sub-module. The types of Layout Managers are a) b) c) d) BorderLayout FlowLayout GridLayout GridbagLayout

FlowLayout In this layout, the components are first added to the center of the container and each additional component is added to the right of the existing component and is then centered. Incase the component does not fit within the border of the container then the component is taken to the next line and again centered and this goes on for all the components. This layout fully maintains the preferred size of components and Panel and Applet have this as the default Layout Manager. The important Constructors are:FlowLayout() - Constructs a new Flow Layout with a centered alignment and a default 5-unit horizontal and vertical gap. FlowLayout(int align) - Constructs a new Flow Layout with the specified alignment and a default 5-unit horizontal and vertical gap. The value of align must be FlowLayout.LEFT, RIGHT, CENTER Code import java.awt.*; class Test104 { Frame f; Button b1; Button b2; public void go() { f=new Frame("FlowLayout Example"); f.setLayout(new FlowLayout()); b1 = new Button("First Button"); b2 = new Button("Second Button"); f.add(b1); f.add(b2); f.pack(); f.setVisible(true); }

public static void main(String args[]) { Test104 a = new Test104(); a.go(); } } Instead of f.pack() change it to f.setSize(200,200) and then we would know the difference. Code import java.awt.*; import java.applet.Applet; public class Test105 extends Applet { Button button1, button2, button3; public void init() { button1 = new Button("Ok"); button2 = new Button("Open"); button3 = new Button("Close"); add(button1); add(button2); add(button3); } } To execute the above code we would require an html file in which the following Applet tag should be there <Applet code=Test105.class height = 400 width=400></Applet> and then call the html file in the browser. BorderLayout This is the default layout manager for Frame and Window. It has five distinct areas: North, South, East, West and Center. It is indicated by BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.EAST, BorderLayout.WEST, and BorderLayout.CENTER. Also incase we do not specify the position mandatorily while adding the components, all the components, would be added to the Center position of the Container. The first way to add components to a container having a Border Layout is add (Component c, int Position). The c over is the component to be added and int position is one of the 5 styles as described above. (e.g. BorderLayout.EAST) IMP: Incase we do not specify the position; the component would be added to the center. The second way to add components in BorderLayout is by using the add (String position e.g. “North”, Component c). When adding a component to a container with a border layout, use one of these five constants, for example:

Panel p = new Panel(); p.setLayout(new BorderLayout()); p.add(new Button("Okay"), BorderLayout.SOUTH); As a convenience, BorderLayout interprets the absence of a string specification the same as the constant CENTER: Panel p2 = new Panel(); p2.setLayout(new BorderLayout()); p2.add(new TextArea()); // Same as p.add(new TextArea(), Code import java.awt.*; public class Test106 extends Frame { Test106() { Button b = new Button("North"); Button b1 = new Button("South"); Button b2 = new Button("East"); Button b3 = new Button("West"); Button b4 = new Button("Center"); add(b, BorderLayout.NORTH); add(b1, BorderLayout.SOUTH); add(b2, BorderLayout.EAST); add(b3, BorderLayout.WEST); add(b4, BorderLayout.CENTER); setSize(400,400); setVisible(true); } public static void main(String arg[]) { new Test106(); } } Output Each of the components would be added their respective positions. For the North and South position the preferred height of the components to be added is taken and then it occupies the whole length of the North and South position. For the East and West position, the preferred width of the components to be added is taken and then it occupies the whole height of the East and West position. Once the four corner positions are taken, the balance space is taken by the Center position. IMP: Incase we do not have any of the 4 corner position, that is no components are added to the 4 corner position, then the Center position would take the balance space also. Code

import java.awt.*; public class Test106A extends Frame { Test106A() { Button b = new Button("OK"); Button b1 = new Button("CANCEL"); Button b2 = new Button("CENTER");

add("North",b); add("West",b1); add(b2); setSize(400,400); setVisible(true); } public static void main(String arg[]) { new Test106A(); } } Output Here we have only two positions occupied and that is North and West and the Center Button takes the remaining position in the size of the Container. VERY IMP: Spellings and Capitalization are important. - You can add only a single component to each of the 5 regions of the BorderLayout manager and if you add more than one, only the one added last is visible. Code import java.awt.*; public class Test106B extends Frame { Test106B() { Button b = new Button("Hi"); Button b1 = new Button("Hello"); Button b2 = new Button("Welcome");

add(b); add(b1); add(b2); setSize(400,400); setVisible(true); } public static void main(String arg[]) { new Test106B();

} } Output Only the Welcome button is shown and it takes the whole container object, this is because we have not specified the position where to place the component objects and all the components have been added to the center and only the last component added is shown. Grid Layout Constructor has parameters for rows and columns Relative position of components does not change Size of component changes Always Ignores the preferred size

Code import java.awt.*; public class Test107 extends Frame { Test107() { setLayout(new GridLayout(3,2)); add(new Button("1")); add(new Button("2")); add(new Button("3")); add(new Button("4")); add(new Button("5")); add(new Button("6")); setSize(200,200); setVisible(true); } public static void main(String arg[]) { new Test107(); } } When both the number of rows and the number of columns have been set to non-zero values, either by a constructor or by the setRows and setColumns methods, the number of columns specified is ignored. Instead, the number of columns is determined from the specified number or rows and the total number of components in the layout. So, for example, if three rows and two columns have been specified and nine components are added to the layout, then they will be displayed as three rows of three columns. Specifying the number of columns affects the layout only when the number of rows is set to zero.


Whenever we need a complex layout and that existing layout managers do not meet our requirements, we will be using a Gridbag layout. It is important over here with, we will be only studying the conceptual basis and no coding is required. The GridBagLayout can be used to layout components in a grid like container layout. Unlike the GridLayout, the sizes of the grids do not need to be constant, and a component can occupy more (or less) than one row or column. Before we go ahead with building the GridbagLayout the following information would be needed : 1. The number of rows and columns required 2. Each component is associated with one area which may be one or more grid rectangles. 3. The number of rows and columns in the grid is determined by the largest values of gridx and gridy. 4. The anchor attribute indicates where in the grid the component will appear in its area if it does not exactly fill its area. 5. The fill attribute determines whether the components should be stretched to fill the entire area. 6. The weight attributes determine the various sizes of the grid areas. The information’s like the weight, fill etc attributes are stored in the GridBagContstraints class and it can be associated with a component using "setContraints (Component, GridBagContraints)" This causes the layout manager to make a copy of the constraints and associate them with the object. Hence we would need only one of these GridBagContraints objects. The following is a complete list of all of the constraints: 1. Anchor determines position in the display area 2. Fill determines if a component is stretched to fill the area 3. Gridheight and gridwidth determine the number of rows and columns in the component's area 4. Gridx and gridy determine the position of the component's area. 5. Insets determine a border around a component's area. 6. Ipadx and ipady allows the minimum or preferred size of a component to be adjusted. 7. Weightx and weighty determine the sizes of the rows and columns of the grids. 8. The weights determine how the extra space is distributed after the components are laid out using their preferred sizes. The algorithm for doing this is simple in the case in which all components have gridwidth and gridheight equal to 1. In this case the weight of a grid column or row is the maximal weight of any component in that column or row.

The extra space is divided based on these weights. For example, if the total weight of all of the columns is 10, then a column with weight 4 would get 4/10 of the total extra space. If there are components which span more than one row or column, the weights are first determined by those components spanning only one row and column. Then each additional component is handled in the order it was added. If its weight is less than the total weights of the rows or columns it spans, it has no effect. Otherwise, its extra weight is distributed based on the weights of those rows or columns it spans. If the extra space is negative, the layout manager squeezes things and you have not control over how this is done. Anchors There are nine anchor types specifying 8 basic compass positions and the center position. NORTH, SOUTH, EAST, WEST, NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST, CENTER Fill The four fill types are NONE (the default), VERTICAL, HORIZONTAL, and BOTH. They affect components whose preferred size does not completely fill their grid area. gridx, gridy The gridx and gridy fields determine the positioning of the components. The default is to put the object in the position after the last one which was added. Internal Padding The fields’ ipadx and ipady can be used to modify the minimum or preferred size of a component. For a button, the preferred width is determined by the length of its label and the preferred height is determined by the font used for the label. Gridwidth and gridheight The gridwidth and gridheight fields determine the number of cells that are included in a component's area. The possible values are a (small) positive integer, or one of the special values REMAINDER or RELATIVE. REMAINDER means the component will occupy all of the cells to the right or below it. RELATIVE means the component will occupy all of the cells to the right or below it except for the last cell. By default, a cell is placed right after the previous one. By setting a width or height to REMAINDER, the component will occupy all cells to the right or below it. By setting the width or height to Relative, the component will occupy all cells to the right or below, except for the last one.

Insets The insets field has four subfields, top, bottom, left, and right. Each controls the size of the border around the component. The defaults are all zero. A negative inset allows a component to extend outside its area. Procedure to create GridBagLayout : 1. Create an Object of type GridBagLayout (without specifying the number of rows and columns) 2. Set this GridBagLayout Object to be the layout manager for the component. 3. Create an object of type GridBagConstraints (will specify how the components are laid out within the Gridbag) 4. For each component, fill in the GridBagConstraints object and call the setContraints object to pass this information to GridBagLayout. 5. Finally, add the components Preferred Size of Components There is a concept of a preferred size of a component which means the default size of a component. If we create a scroll bar in an applet, it would have a default size, but if we place the same scroll bar in any other position in a BorderLayout Container, it would not have its full preferred size. Similarly the preferred size of a button, is the length of its label plus 5 pixels on all the sides of the button. a) b) FlowLayout fully honors the preferred size of any component. BorderLayout partially honors the preferred size of a component. The width is honored when place on the West and East side of the BorderLayout. For example, when the size of the BorderLayout Container is changed, the width position of the West and East side does not change. Similarly the height is honored by the North and South positions of the BorderLayout Container c) d) The GridLayout does not honor the preferred size of the component at all. The GridbagLayout also does not honor the preferred size of the component.

Graphics class and painting of components

Java’s painting mechanism provides the way for one to render our components and the mechanism is robust and if we use it correctly it can create a good scaleable re-usable code. The fundamental concepts of painting are a) The paint () method and the graphics context.

b) The repaint () method c) Painting to Images. Any kind of component can be associated with the graphics context, but it is unusual to do so that components that already have an appearance. The Visual components do not require painting. However there are 4 classes of blank components that have no default appearance and will shop as empty rectangles unless sub-classed or instantiated and given paint () methods and these components are:a) b) c) d) Applet Canvas Frame Panel

The paint method already has a Graphics class as its parameter and the 3 major operations provided by the Graphics class are: a) b) c) Selecting a Color Selecting a font Drawing and Filling

Initially we will do the Drawing and Filling methods of the Graphics class and we will look at the following methods:a) b) c) d) e) drawString ( String s, int x-cor, int y-cor); drawLine(int x0, int y0, int x1, int y1); drawOval(int x, int y, int width, int height) and fillOval. drawRect(int x. int y, int width, int height) and fillRect drawArc(int x, int y, int width, int height, int startdegree, int arcdegree) and fillArc. drawPolygon(int x[], int y[], int points) and fillPolygon drawPolyline(int x[], int y[], int points)

f) g)

IMP: For parameters for the fill methods is the same at the draw methods, only it is done after setting a Color and the object is filled with the specified color. Code import java.awt.*; public class Test96 extends Frame { public static void main(String[] args) { new Test96(); } Test96() { super("My Frame");

setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { g.drawString("Hello",100,100); } } Output There would a window the size of 400 by 400 from the left top corner and within that Hello would be printed at approx 100 by 100 point. Code import java.awt.*; public class Awt1 extends Frame { public static void main(String[] args) { new Awt1(); } Awt1() { super("My Frame"); setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { g.drawLine(10,20,250,360); } } Output Over here with starting point is 10,20 where 10 is the x axis and 20 being the y axis starting point and the line goes up to 250,360. import java.awt.*; public class Awt2 extends Frame { public static void main(String[] args) { new Awt2(); } Awt2() {

super("My Frame"); setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { g.drawRect(100,200,100,50); } } Output Draws a rectangle as per the specified size and over here with 3rd and 4th parameter is the width and height of the rectangle to be drawn. Code import java.awt.*; public class Awt3 extends Frame { public static void main(String[] args) { new Awt3(); } Awt3() { super("My Frame"); setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { g.drawArc(100,200,100,50,20,150); } } Output Draws the specified arc as per the dimensions provided. It is important to note over here that the Arc Start Angle is 0 degree at 3 o’clock position and a positive value indicates anti clock wise movement and a negative value indicates a clock wise motion. The center of the arc is the center of the rectangle drawn with the x, y position specified and the width and height specified. Selecting the Color Colors can be selected by calling the setColor () method. The argument is an instance of the Color class. There are approx 13 pre-defined colors accessible as static final variables in the Color class usually known as constants of the Class.

Incase the above set of colors are not enough, we can call the Color constructor which takes rgb (red, green and blue) and pass this instance to the setColor method. The setColor method only changes the future color drawings after the color has been set. Code import java.awt.*; public class Test97 extends Frame { public static void main(String[] args) { new Test97(); } Test97() { super("My Frame"); setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { Color c = new Color(100,200,250); g.setColor(; g.setColor(c); g.fillOval(20,30,150,100); }


} Output An oval shape filled with red color would come at 20 by 30 location and having a width of 150 and height of 100. We can uncomment the g.setColor(c) and see the output also. For trying out with a polygon, we have a sample code as under:Code import java.awt.*; public class Test98 extends Frame { public static void main(String[] args) { new Test98(); } Test98() { super("My Frame"); setSize(400,400);

setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { int x[]= {10,30,50}; int y[]= {50,150,179}; g.drawPolygon(x,y,3); } } IMP: The difference between drawPolygon and drawPolyline is that, a polygon is enclosed whereas the last section in the polyline is not enclosed. Also incase we give the 3rd parameter in either of them as a value more than the number of points declared in the array, then an ArrayIndexOutOfBoundsException would be thrown. Selecting the Font The Constructor of the Font class has 3 parameters namely:Font name int style which would be Font.BOLD or Font.ITALIC or Font.Plain. int size Similar to the setColor, we have to use the method setFont and all subsequent operations would take that Font. Code import java.awt.*; public class Test99 extends Frame { public static void main(String[] args) { new Test99(); } Test99() { super("My Frame"); setSize(400,400); setVisible(true); setLayout(new FlowLayout()); } public void paint(Graphics g) { Font f = new Font("Arial", Font.BOLD,36); g.setFont(f); g.drawString("This will come big",100,100); } }

repaint () method Many a times we would want the complete screen to be re-drawn based on something and at these times we would always call the re-paint () method only. The repaint () method calls the update () method, which clears the screen and then again draws as per the background color of the component and then update () calls the paint () method. Incase we want what is draw earlier to be there on the screen but also the new details to also be drawn (to draw concentric circles), then we need to override update () which also takes a Graphics handle and call paint directly inside update (). Incase we do not override, then it would call the default update () method which will erase all the earlier contents and then call paint(). At many times, there are automatic calls to the paint method by the JVM itself. It is the GUI thread which makes these calls to paint (). Every applet or application that has a GUI has a GUI thread. The GUI thread spontaneously calls the paint () method under 4 circumstances, two of which are only applicable to applets: a) b) c) d) After exposure After deiconification Shortly after init () method returns (only applets) When a browser returns to a previously displayed page containing an applet, provided the applet is atleast partially visible.

Images Images are off screen representation of rectangular pixel patterns. We can either create an image or draw an existing image to the screen. To create a image we would call the createImage () method of the Component class To draw an existing gif or jpeg file, we should first call the getImage () method of the Applet class which returns an Image object and then call the drawImage () method to draw the same. The above example can be proved only on an applet which is not a part of certification, but the important is just the conceptual knowledge of the methods. Image I = getImage (getDocumentBase(),”name of image”); The image file called “name of image” should be stored in the directory in which the .java file is there. The code for creating a new Image would like Image i = createImage(300,200); which is width and height of image. Graphics g = i.getGraphics(); g.setColor(Color.yellow); g.fillRect(0,0,100,100); g.fillOval(110,110,100,100); Then within paint we would draw the image g.drawImage(i,20,30,this);

Non-Menu Components

Label Label is effectively text strings that you can use to label other UI components. The advantage that a label has over an ordinary text string is that it follows the layout of the given panel and you do not have to worry about repainting it every time the panel is redrawn. Labels also can be easily aligned within a panel, enabling you to attach labels to other UI components without knowing exact pixel position.


To create a label, one of the following constructors is used: Label () Label (String t) Creates an empty label Creates a label with the given text string and aligned left Creates a label with the given text string and the given alignment.

Label (String t, int alignment) -

The available alignments are stored in class variables in Label, making them easier to remember. Label.RIGHT, Label.LEFT, Label.CENTER. You can add a Label with the following command. add(new Label(“Hello”, Label.CENTER)); Once 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. Button The Button is the simples UI components that trigger some action in your interface when they are pressed. They are usually used for Ok and Cancel buttons in dialog box.


To create a button, one of the constructors used are: Button () Button (String t) Creates an empty button with no label. Creates a button with the given string object 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) methods. You can add a button as under: add(new Button (“OK”)); Button b = new Button (“First”); add(b); When a Button is pushed, it sends an Action Event. or by using the following statement

Canvas A canvas is a component that has no default appearance or behavior. You can subclass canvas to create drawing regions, work areas, components and so on.

The default size of the canvas is uselessly small and one way to deal with this problem is to use a layout manager that will resize the canvas and the other way to call setSize () on the canvas ourselves. For e.g. Code import java.awt.*; import java.applet.*; public class Test109 { Test109() { Frame f= new Frame("Frame1"); f.setLayout(new FlowLayout()); Canvas c = new Canvas(); c.setBackground(; c.setSize (100,50); f.add(c); f.setSize(300,300); f.setVisible(true); } public static void main(String arg[]) { new Test109(); } } Code (for showing Label and Button) import java.awt.*; public class NonMenu1 extends Frame { NonMenu1() { Label a = new Label("Label A"); Label a1 = new Label("Label B"); Button b = new Button("North"); Button b1 = new Button("South"); setLayout(new FlowLayout()); add(a); add(a1); add(b); add(b1); setSize(400,400);

setVisible(true); } public static void main(String arg[]) { new NonMenu1(); } } Output Two Labels and Two Buttons would be shown in one line. Checkbox Checkboxes are user interface components that have two states on and off, checked and unchecked etc. Unlike Buttons, Checkboxes usually do not trigger direct action in an UI, but instead are used to indicate optional features of some action. Checkboxes can be used in two ways: 1. Non-Exclusive, meaning that given a series of checkboxes, any of them can be selected. 2. Exclusive meaning that within one series, only one checkbox can be selected at a time. The latter kinds of checkboxes are called radio buttons or checkbox groups and non-exclusive checkboxes can be created by using the Checkbox Class. To create a Checkbox Checkbox () Checkbox (String t) Checkbox (String t boolean b CheckboxGroup c) creates an empty checkbox, unselected. creates a checkbox with the string as a label. creates a checkbox that is either selected or unselected based on whether the boolean condition is true or false



If you do not specify an initial input, the default is false. Checkboxes send Item Events when they are selected. Code import java.awt.*; import java.applet.*; public class Test108 { Checkbox cb1; Checkbox cb2; Checkbox cb3; Test108() {

Frame f= new Frame("Frame1"); cb1 = new Checkbox("Java"); cb2 = new Checkbox("C++"); cb3 = new Checkbox("VB"); f.setLayout(new FlowLayout()); f.add(cb1); f.add(cb2); f.add(cb3); f.setVisible(true); f.setSize(200,200); } public static void main(String arg[]) { new Test108(); } } CheckboxGroup It is very important to note that this is not a UI component. However it can be used to create an association between collections of Checkbox components. When you instantiate a CheckboxGroup object and use it to create a set of Checkbox controls. only one of those Checkbox controls can be selected at a time. To create a series of Checkbox controls, first create an instance of CheckboxGroup. CheckboxGroup c = new CheckboxGroup(); Then create and add the individual checkboxes using the group as the second argument and whether or not that checkbox is selected (only one in the series can be selected). add (new Checkbox (“System Analyst”, c, false); add (new Checkbox (“System Auditor”, c, false); add (new Checkbox (“System Manager”, c, false); There are two methods in CheckboxGroup and they are: getSelected Checkbox () setSelected Checkbox () Gets current selected check box Sets the current choice to the specified Checkbox.


Code import java.awt.*; import java.applet.*; public class Test110 { Checkbox cb1; Checkbox cb2; Checkbox cb3;

Test110() { Frame f= new Frame("Frame1"); CheckboxGroup cb = new CheckboxGroup(); cb1 = new Checkbox("Java",cb,true); cb2 = new Checkbox("C++",cb,false); cb3 = new Checkbox("VB",cb,false); f.setLayout(new FlowLayout()); f.add(cb1); f.add(cb2); f.add(cb3); f.setVisible(true); f.setSize(200,200); } public static void main(String arg[]) { new Test110(); } } Choice The Choice class encapsulates a drop down choice list component. The choice component allows a user to select one of the several options or items in one place. To create a choice list, create a instance of the Choice class and then use addItem () method to add individual items to it in the order in which they should appear.

The class Choice provides methods that allow you to access or set the currently selected item in the list. Checkboxes send Item Events when they are selected. Code import java.awt.*; public class NonMenu2 extends Frame { NonMenu2() { Choice c = new Choice(); c.add("Bombay"); c.add("Delhi"); c.add("Calcutta"); setLayout(new FlowLayout()); add(c); setSize(400,400); setVisible(true); } public static void main(String arg[]) {

new NonMenu2(); } } Output A drop down would be shown, having the contents of the items added to it. List A scrolling list presents a scrolling list of choices that the user can select from or scroll, using the up and down arrow that appear at right in the list control. If a list contains more items than it can display, it requires a vertical scroll bar. The three forms of constructors are: List () List (int visiblerows) List (int visiblerows, boolean select) The number of visiblerows dictates the height of a list. The first version does not specify the number of visible rows and hence the height is dictated by a layout manager. If the version of the third constructor is used and boolean select is true, then the list supports multiple selection. If multiple selection is not enabled, then selecting a new item causes the old selected item to be deselected. To create a list, create an instance of List class and then addItem () method to add individual items to it in the order in which they should appear.




Lists are used when multiple selection are needed. Selecting an item in a list causes the list to send a Item event and double clicking an item sends an Action Event. Code import java.awt.*; public class NonMenu3 extends Frame { NonMenu3() { List l = new List(3,true); l.add("Bombay"); l.add("Delhi"); l.add("Calcutta"); l.add("Madras"); l.add("Jaipur"); setLayout(new FlowLayout()); add(l); setSize(400,400); setVisible(true);

} public static void main(String arg[]) { new NonMenu3(); } } Output A list box containing 3 items would be generated and it automatically has a scroll bar since, we have more than 3 items in the code and multiple selection is also enabled to be true.

Scrollbar Scrollbars are used most often when only a part of an entity (document, picture etc) can be displayed by the application and one has to scroll to see the balance. The most common placement of scrollbars is to the right and bottom of the window. The three constructors are: Default vertical Scrollbar constructs a scroll bar with the specified orientation


Scrollbar () Scrollbar (int orientation) Scrollbar (int orientation int initialValue int sliderSize int minValue int maxValue)

For constructors that take a orientation parameter, this value should be one of the following: Scrollbar.HORIZONTAL Scrollbar.VERTICAL For the third constructor, the piece of the scrollbar that slides is the slider. The sliderSize parameter controls the size of the slider but not in pixel units. The units of the sliderSize parameter are the units defined by the spread between the minimum and maximum values of the scrollbar. For example, consider a horizontal scroll bar whose minimum value is 600 and maximum value is 700. The spread covered by the scrollbar is the difference between the two numbers or 100. A sliderSize value of 50 would represent half the spread and the slider would be half the width of the scrollbar. A sliderSize value of 10 would represent half the spread the slider would be one-tenth the width of the scrollbar. For Example: Scrollbar sb = new Scrollbar (Scrollbar.HORIZONTAL, 625,25,600,700);



The above line of code creates a Horizontal scroll bar with the range from 600 to 700 and the initial value is 625. The slider size is 25 out of the range between 700 - 600 so the slider size should be 1/4th the width of the scroll bar. Scroll bars generate Adjustment Events Code

import java.awt.*; public class NonMenu4 extends Frame { NonMenu4() { Scrollbar s = new Scrollbar(Scrollbar.HORIZONTAL,100,50,0,300); setLayout(new FlowLayout()); add(s); setSize(400,400); setVisible(true); } public static void main(String arg[]) { new NonMenu4(); } } Output We should see a scrollbar with its preferred size, since it is a flow layout. The 2nd parameter specifies the starting point the slider and since the range is from 0 to 300 and the slider starting point is 100, we actually see the slider moved in the output. Now let us see the same output with BorderLayout Code import java.awt.*; public class NonMenu4 extends Frame { NonMenu4() { Scrollbar s = new Scrollbar(Scrollbar.HORIZONTAL,100,50,0,300); add(s,BorderLayout.SOUTH); setSize(400,400); setVisible(true); } public static void main(String arg[]) { new NonMenu4(); } } Output We see here the same slider, but only the height of it is honored, since it is added to the South position. TextComponent


The TextComponent is the superclass of the TextField and TextArea classes. These classes provide methods that make it possible to get and set both the full text with the UI component and currently selected text within the component. All the TextComponent methods are available for both the TextField and TextArea classes.


TextField The TextField enables the user to enter information into a TextField. The TextField components can be created as empty or with an initial String. The TextField components can be defined to have an initial number of columns. If you do not define an initial number of columns, then the layout manager may use the TextField components initial text value to determine the TextField component’s appropriate length. The TextField class inherits most of its functionality from TextComponent. The constructors for the TextField are: Constructs an TextField Constructs the TextField with specified number of columns


TextField () TextField (int cols)

TextField (String txt)


Constructs the TextField with specified Text Constructs the TextField with specified Text and number of columns.

TextField (String t, int cols) -

TextArea The TextArea component can contain multiple lines of text. Like the TextField component, TextArea components can also be created either empty or with an initial string. TextArea component can be defined with an initial number of rows and columns. The TextArea component inherits most of its functionality from the TextComponent. The following are the TextArea constructors: Constructs the new TextArea


TextArea () TextArea ( int rows, int cols)

Constructs the TextArea with the specified number of rows and columns. Constructs the TextArea with the specified String displayed. Constructs the TextArea with specified text, number of rows and columns.

TextArea (String text)


TextArea (String t, int rows, int cols) -


A Dimension object defines the size of an entity, typically in pixels. The TextArea class method, getMinimumSize () and getPreferredSize () both translate a specified number of rows and columns in a TextArea object to the appropriate dimensions measured in pixels.

Code import java.awt.*; class Test111 { public static void main(String[] args) { Frame f = new Frame("First Frame"); f.setLayout(new FlowLayout()); Label a = new Label("Login"); Label b = new Label("Password"); TextField tf1 = new TextField(20); TextField tf2 = new TextField(20); f.add(a); f.add(tf1); f.add(b); f.add(tf2); f.validate(); f.repaint(); //f.setVisible(true); //f.setSize(200,400);; f.pack(); } } The method validate will force the container to reorder the components and repaint will again enables the drawing of the components to the screen. Code (Example of Text Area) import java.awt.*; public class NonMenu5 extends Frame { NonMenu5() { TextArea ta = new TextArea(5,8); add(ta); setLayout(new FlowLayout()); setSize(400,400); setVisible(true); } public static void main(String arg[]) {

new NonMenu5(); } } Code (Example of Panel). import java.awt.*; class Test114 { public static void main(String[] args) { Frame f = new Frame("Sixth"); Panel p = new Panel(); Panel p1 = new Panel(); Label l = new Label("Name"); TextField tf = new TextField(20); Button b = new Button("Ok"); Button b1 = new Button("Cancel"); p.add(l); p.add(tf); p1.add(b); p1.add(b1); p.setBackground(; p1.setBackground(;

f.add("North" , p); f.add("South",p1); f.setBackground(; f.setVisible(true); f.setSize(200,400); f.validate(); f.repaint(); } }

Menu components


Java provides several classes that allow menu bars to be constructed and attached to a Frame window. These classes are directly descended from the Object class and are not subclasses of the component class. The MenuComponent class is the superclass of the menu-related classes and provides a common set of methods that are used by its subclasses. The MenuComponent class provides a default parameterless constructor, although objects of this class should not be directly created.




The MenuBar Class


The MenuBar class implements a menu bar that is attached to a Frame window. It provides a default parameterless constructor and several access methods for adding and removing Menu objects from the menu bar. It also provides methods that are used to return the current number of menus and to get and set a special help menu.


The MenuItem Class The MenuItem class is used to implement items that may be selected from a pull-down menu. The Menu and CheckboxMenuItem classes extend it. The MenuItem class implements items that can be selected from a pull-down menu. Because the Menu and CheckboxMenuItem classes subclass it, it provides the capability for objects of these classes to be selected from a pull-down menu. This allows multiple levels of menus to be implemented. The MenuItem class provides a single constructor that takes a String object as a parameter. The String object is used as the label of the menu item.



The Menu Class The Menu class implements a single pull-down menu that is attached to a menu bar or other menu. It provides two constructors that allow the menu's label to be specified and determine whether it is to be implemented as a tear-off menu. It also provides methods that are used to add or remove menu items, add menu separators, count the number of items in the menu, and determine what menu item is currently selected.



The CheckboxMenuItem Class The CheckboxMenuItem class is used to implement menu items that may be checked on or off. It provides a single constructor that contains the label to be used with the checkbox menu item. The setState() and getState() methods are used to determine the checked state of the menu item.



Code import java.awt.*; class Test115 { public static void main(String[] args) { Frame f = new Frame("Menu");

MenuBar mb = new MenuBar(); Menu m = new Menu("File"); Menu m1 = new Menu("Edit"); Menu m2 = new Menu("View"); MenuItem mi1 = new MenuItem("Open"); MenuItem mi2 = new MenuItem("Save"); MenuItem mi3 = new MenuItem("Exit"); m.add(mi1); m.add(mi2); m.add(mi3); mb.add(m); mb.add(m1); mb.add(m2); f.setMenuBar(mb); f.setVisible(true); f.setSize(200,400); f.validate(); f.repaint(); } }

Events Handling Concepts

The user communicates with the programs by performing actions like clicking on a Button and these actions results in generation of events. The Events are objects that describe what has happened, the process of responding to an event is known as event handling. The object which generated the event is known as Event Source e.g. a mouse click on a Button component generates an ActionEvent with the Button as the source of the event. The method which receives the event, processes the event and does something on the event being generated is known as the Event Handler. The Event Handlers are the methods, which are within the Event Listeners in the Event Delegation Model followed by Java. The Event class defines the list of events handled by programs and also provides constructors for constructing events, but we do not need to use these constructors as the events are internally generated by the Java runtime system in response to user interface actions. The Event class also provides methods for determining whether the Control, Shift, or Meta (Alt) keys were pressed during the generation of an event. Event Listeners An event listener is an object to which a component has delegated the task of handling a particular kind of event.


When an event experiences input, an event of the appropriate type is constructed; the event is then passed as the parameter to a method call on the listener. We should ensure that the listener must implement the interface that contains the event handling method. A component may have multiple listeners for any event type. There is no guarantee that listeners will be notified in the order in which they were added. There is no guarantee that listener notification will occur in the same thread; thus listeners must take precautions against corrupting shared thread. The return type of all Listeners are void.




An event listener may be removed from a component’s list of listeners by calling a removeXXXListener() method, passing in the listener to be removed. Adapter Classes Since we have more than one method in many event listener interfaces, we already have adapter classes overriding them with blank implementation and hence we can use only the method which we want by overriding that particular method only. So all the Event Listeners which has more than one event handler method has a Adapter class. The disadvantage is that if our class already extends any other class, we cannot use the Adapter classes. The Adapter Classes are 1. 2. 3. 4. 5. 6. 7. ComponentAdapter ContainerAdapter FocusAdapter KeyAdapter MouseAdapter MouseMotionAdapter WindowAdapter

Events in Java

There are basically 11 events in java and each of the components may generate any one or more of the events based on some conditions Whenever we are working with events we should import the java.awt.event package. A common question is when we import java.awt is the java.awt.event package not imported. The answer is no, since when we import a package all the classes in the package is imported and not the sub packages. The events in java are:ActionEvent This event indicates that a component defined action has occurred. This event will be generated by a component (Button or a Menu) when the component specific action occurs (such as being

pressed). The event is then passed to every ActionListener object that is registered to receive such events using the Component’s addActionListener method. The Object that implements the ActionListener interface get this ActionEvent when the event occurs and is passed to the Event Handler method called actionPerformed() which takes the Action Event as its parameter. The return type of all Event Handler methods is void. AdjustmentEvent This event is fired by adjustable objects like Scrollbar components, when ever there is a change in its slider position. Focus Event This event indicates whether the component has gained or lost the keyboard focus. This event is generated by a component (like Text Field) and the event is the passed to every FocusListener or FocusAdapter object which is registered to receive such events using the component’s addFocusListener () method. Each of the listener objects gets the Focus Events when the event is generated. ItemEvent This event indicates that an item was selected or deselected. This event is generated by an ItemSelectable object (such as List, Choice or Checkbox) when an item is selected or deselected. The item is then passed to every ItemListener object which is registered to receive such events using the component’s addItemListener method. ContainerEvent This event indicates that a container’s contents changed because a component was added or removed. The Container Events are provided for notification purposes only. The AWT will automatically handle these changes to the containers contents internally so that the program works properly regardless of whether the program is receiving the events or not. This event is generated by a container object (such as Panel, Frame etc) when a component is added to it or removed from it. ComponentEvent This event indicates that a component moved, changed size or changed visibility. This is also the root class for the other component level events. The Component events are also provided for notification purposes only. The AWT will automatically handle component moves and resizes internally so that the GUI layout works properly regardless of whether a program is receiving these events or not. This event is generated by any component object when the component is moved, resized, rendered invisible and made visible again. The important method in this class is the getComponent () method which returns the Component Object which generated the Event. KeyEvent This event is generated by a component object (a Text Field) when a key is pressed, released or typed. The key typed events generally do not depend on the platform or keyboard layout. They

are generated when a character is entered and it is also possible to check with additional keys like Ctrl or Alt or Shift keys were pressed along with it. Normally the function keys would generate only pressed and released event changes because they cannot be typed. MouseEvent This is an event which indicated that a mouse action has occurred in a component. This event is used for both mouse events and mouse motion events (like drag and move). Note that there is a separate Listener called MouseMotionListener whose Event Handlers also take MouseEvent as its parameter. The important methods in this event are a) getPoint () which returns a Point, that is the x and y position of the event relative to the source component. getX () which returns an int which returns the horizontal x position of the event relative to the source component. getY() which returns an int which returns the vertical y position of the even relative to the source component



TextEvent This event is generated by components like (TextArea and TextField) whenever a character is entered into its area. WindowEvent This event indicates that a window has changed its status. This event is generated by a Window object when it is opened, closed, about to close, activated or deactivated, iconified or deiconified. This event is generally fired by the Container classes (especially the Frame) and has got 7 types of Event Handlers in the WindowListener.

Event Handler for each of the Events

The Event Handler is the method present within the EventListener which handles the respective Event generated. Note that all the respective Event Handlers take the respective event as their parameters, so that the events can be properly processed with the Event Handler. It is also important to note that the event listener should be registered with the components for the Event Handlers to effectively process the events. The following table shows the Event Handlers for each of the Listeners for the different types of Events. Interface Name ActionListener Event ActionEvent Methods in interface actionPerformed(ActionEvent) Add method addActionListener()

AdjustmentListene AdjustmentEvent r ComponentListen ComponentEvent er

adjustmentValueChanged(AdjustmentEv addAdjustmentListener() ent) componentHidden(ComponentEvent) addComponentListener() componentMoved(ComponentEvent) componentResized(ComponentEvent) componentShown(ComponentEvent) ContainerListener ContainerEvent componentAdded(ContainerEvent) addContainerListener() componetRemoved(ContainerEvent) FocusListener FocusEvent focusGained(FocusEvent) addFocusListener() focusLost(FocusEvent) InputMethodListen InputMethodEvent caretPositionChanged(InputMethodEven addInputMethodListener( er t) ) inputMethodTextChanged(InputMethodE vent) ItemListener ItemEvent itemStateChanged(ItemEvent) addItemListener() KeyListener KeyEvent keyPressed(KeyEvent) addKeyListener() MouseListener MouseEvent mouseClicked(MouseEvent) addMouseListener() mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) MouseMotionListe MouseEvent mouseDragged(MouseEvent) addMouseMotionListene ner mouseMoved(MouseEvent) r() TextListener TextEvent textValueChanged(TextEvent) addTextListener() WindowListener WindowEvent windowActivated(WindowEvent) addWindowListener() windowClosed(WindowEvent) windowClosing(WindowEvent) windowDeactivated(WindowEvent) windowDeiconified(WindowEvent) windowIconified(WindowEvent) windowOpened(WindowEvent) Some of the Example of how to handle events for different types of components are shown in the below codes. Each of the code show different type of events and how they are effectively handled.

Using Events with Components

Code - Example of Action Event import java.awt.*; import java.awt.event.*; public class Test117 implements ActionListener { Button b1; Button b2; public Test117() { Frame f = new Frame("Frame1"); f.setLayout(new FlowLayout()); b1 = new Button("Ok"); b2 = new Button("Cancel");

f.add(b1); f.add(b2); f.setVisible(true); f.setSize(200,200); b1.addActionListener(this); b2.addActionListener(this); } public static void main(String[] args) { new Test117(); } public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("Ok")) { System.out.println("Button 1 clicked"); } else if(e.getSource()==b2) { System.out.println("Button 2 clicked"); } } } Code - Another Example of Action Event import java.awt.*; import java.awt.event.*; import java.applet.*; public class ChoiceEvent extends Applet implements ActionListener { TextField tf; Choice c; Button b1; Button b2; public void init() { tf = new TextField(20); add(tf); b1 = new Button("ADD"); b2 = new Button("REMOVE"); c = new Choice(); c.add(" "); add(b1); add(b2); add(c); b1.addActionListener(this); b2.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if(ae.getSource() == b1)

{ c.add(tf.getText()); } else if(ae.getSource()==b2) { String s = c.getSelectedItem(); c.remove(s); } } } //<Applet code="ChoiceEvent.class" width ="300" height = "300"></Applet> Code - Example of Focus Event import java.awt.*; import java.awt.event.*; import java.applet.*; public class FocusEvent1 extends Applet implements FocusListener { TextField tf = new TextField(20); TextField tf1 = new TextField(20); TextArea ta = new TextArea(10,20); public void init() { add(tf); add(tf1); add(ta); tf.addFocusListener(this); tf1.addFocusListener(this); ta.addFocusListener(this); } public void focusGained(FocusEvent fe) { ta.append("Focus is gained\n"); } public void focusLost(FocusEvent fe) { ta.append("Focus is lost\n"); } } //<Applet code = "FocusEvent1.class" height="300" width ="300"></Applet> Code - Example of Item Event import java.awt.*; import java.applet.*; import java.awt.event.*; public class Item1 extends Applet implements ItemListener { Checkbox cb1; Checkbox cb2;


Checkbox cb3; public void init() { Frame f= new Frame("Frame1"); cb1 = new Checkbox("Java"); cb2 = new Checkbox("C++"); cb3 = new Checkbox("VB"); f.setLayout(new FlowLayout()); f.add(cb1); f.add(cb2); f.add(cb3); f.setVisible(true); f.setSize(200,200); cb1.addItemListener(this); cb2.addItemListener(this); cb3.addItemListener(this); } public void itemStateChanged(ItemEvent e) { repaint(); } public void paint(Graphics g) { g.drawString(cb1+"checked = "+cb1.getState(),25,100); g.drawString(cb2+"checked = "+cb2.getState(),25,130); g.drawString(cb3+"checked = "+cb3.getState(),25,150); } } //<Applet code ="Item1.class" height="200" width="200"></Applet> Code - Example of KeyEvent import java.awt.*; import java.applet.*; import java.awt.event.*; public class KeyEvent1 extends Applet implements KeyListener { TextField tf; TextArea ta; public void init() { tf = new TextField(20); ta = new TextArea(10,20); add(tf); add(ta); tf.addKeyListener(this); ta.addKeyListener(this); } public void keyPressed(KeyEvent ke)

{ ta.append("pressed :\n"); } public void keyTyped(KeyEvent ke) { ta.append("typed :\n"); } public void keyReleased(KeyEvent ke) { ta.append("released :\n"); } } //<Applet code="KeyEvent1.class" height="200" width ="300"></Applet> Code - Example of Action Event with Menu Components and File Dialog import java.awt.*; import java.applet.*; import java.awt.event.*; public class MenEvt extends Applet implements ActionListener { Frame f; MenuBar mb; Menu m,m1,m2; MenuItem mi1,mi2,mi3; Dialog d ; FileDialog fd; Button b,b1; public void init() { f = new Frame("Menu"); mb = new MenuBar(); m = new Menu("File"); m1 = new Menu("Edit"); m2 = new Menu("View"); mi1 = new MenuItem("Open"); mi2 = new MenuItem("Save"); mi3 = new MenuItem("Exit"); m.add(mi1); m.add(mi2); m.add(mi3); mi1.addActionListener(this); mi2.addActionListener(this); mi3.addActionListener(this); mb.add(m); mb.add(m1); mb.add(m2); f.setMenuBar(mb);

f.setVisible(true); f.setSize(200,400); f.validate(); f.repaint(); } public void actionPerformed(ActionEvent ae) { if(ae.getSource()== mi3) { d = new Dialog(f,"First",true); Label l = new Label("Are you sure you want to exit"); Panel p = new Panel(); b = new Button("Ok"); b1 = new Button("Cancel"); b.addActionListener(this); b1.addActionListener(this); p.add(b); p.add(b1); d.add(p); d.add("North",l); d.setSize(200,200);; } else if(ae.getSource()== b) { d.hide(); } else if(ae.getSource()== b1) { d.dispose(); } else if (ae.getSource()==mi1) { d = new FileDialog(f,"FirstFile",FileDialog.LOAD);; } else if (ae.getSource()==mi2) { d = new FileDialog(f,"FirstFile",FileDialog.SAVE);; } } } //<Applet code = "MenEvt.class" height= 200 width =300></Applet> Code - Example of Mouse Event import java.awt.*; import java.applet.*;

import java.awt.event.*; public class MouseEvent1 extends Applet implements MouseListener { TextArea ta; TextArea ta1; public void init() { ta = new TextArea(10,20); ta1 = new TextArea(10,20); add(ta); add(ta1); ta.addMouseListener(this); ta1.addMouseListener(this); } public void mousePressed(MouseEvent ke) { int x = ke.getX(); int y= ke.getY(); ta1.append("pressed :x:"+x+"y:"+y+"\n"); } public void mouseExited(MouseEvent ke) { int x = ke.getX(); int y= ke.getY(); ta1.append("exited :x:"+x+"y:"+y+"\n"); } public void mouseClicked(MouseEvent ke) { int x = ke.getX(); int y= getY(); ta1.append("clicked :x:"+x+"y:"+y+"\n"); } public void mouseEntered(MouseEvent ke) { int x = ke.getX(); int y = ke.getY(); ta1.append("Entered :x:"+x+"y:"+y+"\n"); } public void mouseReleased(MouseEvent ke) { int x = ke.getX(); int y= ke.getY(); ta1.append("released :x:"+x+"y:"+y+"\n"); } } //<Applet code="MouseEvent1.class" height="200" width ="300"></Applet>

Code - Example of Mouse Motion Listener import java.awt.*;

import java.applet.*; import java.awt.event.*;

public class MouseEvent2 extends Applet implements MouseMotionListener { TextArea ta; TextArea ta1; public void init() { ta = new TextArea(10,20); ta1 = new TextArea(10,20); add(ta); add(ta1); ta.addMouseMotionListener(this); ta1.addMouseMotionListener(this); } public void mouseDragged(MouseEvent ke) { int x = ke.getX(); int y = ke.getY(); ta1.append("Dragged :x:"+x+"y:"+y+"\n"); } public void mouseMoved(MouseEvent ke) { int x = ke.getX(); int y= ke.getY(); ta1.append("Moved :x:"+x+"y:"+y+"\n"); } } //<Applet code="MouseEvent2.class" height="200" width ="300"></Applet> Code - Example of Adjustment Event import java.awt.*; import java.applet.*; import java.awt.event.*; public class ScrollEvent extends Applet implements AdjustmentListener { Scrollbar sb,sb1,sb2; public void init() { //ame f = new Frame("Frame 1"); sb = new Scrollbar(Scrollbar.VERTICAL,0,0,0,255); sb1 = new Scrollbar(Scrollbar.HORIZONTAL,0,0,0,255); sb2 = new Scrollbar(Scrollbar.VERTICAL,0,0,0,255); setLayout(new BorderLayout()); add("East",sb);

add("North",sb1); add("West",sb2); sb.addAdjustmentListener(this); sb1.addAdjustmentListener(this); sb2.addAdjustmentListener(this); } public void adjustmentValueChanged(AdjustmentEvent ae) { Color c = new Color(sb.getValue(),sb1.getValue(),sb2.getValue()); setBackground(c); repaint(); } } //<Applet code ="ScrollEvent.class" height="300" width ="300"></Applet> Code - Example of Window Event import java.awt.*; import java.applet.*; import java.awt.event.*; public class WindowEvent1 extends Applet implements ActionListener,WindowListener { Button b1,b2; TextArea ta; Frame f; String s1,s2; public void init() { b1 = new Button("Add"); b2 = new Button("Remove"); f = new Frame("One"); f.addWindowListener(this); add(b1); add(b2); ta = new TextArea(20,20); add(ta); b1.addActionListener(this); b2.addActionListener(this); } public void actionPerformed(ActionEvent ae) { if (ae.getSource()==b1) { f.setVisible(true); f.setSize(200,200); validate(); repaint();

} if (ae.getSource()==b2) { f.setVisible(false); validate(); repaint(); } } public void windowActivated(WindowEvent ce) { ta.append("activated\n"); } public void windowDeactivated(WindowEvent ce) { ta.append("deactivated\n"); } public void windowIconified(WindowEvent ce) { ta.append("iconified\n"); } public void windowDeiconified(WindowEvent ce) { ta.append("DeIconified\n"); } public void windowOpened(WindowEvent ce) { ta.append("opened\n"); } public void windowClosed(WindowEvent ce) { ta.append("closed\n"); } public void windowClosing(WindowEvent ce) { ta.append("closing\n"); //System.exit(1); f.dispose(); } } //<Applet code="WindowEvent1.class" height ="300" width ="300"></Applet>

Anonymous Class


Classes that do not need a name One cannot use new in the usual way since we cannot create an instance of this class

Button.addActionListener( new ActionListener() { public void actionPerformed (ActionEvent e) { System.out.println(“The action has occurred”); } } ) Remember that the whole class is within the parameters of the addActionListener method. Anonymous class cannot have a constructor. Anonymous class can be a subclass of another explicit class or it can implement a single explicit interface.

Code import java.awt.*; import java.awt.event.*; public class Test116 { Frame f; Test116() { f= new Frame("Frame 1"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(1); } } ); f.setSize(100,100); f.setVisible(true); } public static void main(String[] args) { new Test116(); } }

Swing Components

The base class for all Swing components except top-level containers. To use a component that inherits from JComponent, you must place the component in a containment hierarchy whose root is a top-level Swing container. Top-level Swing containers -- such as JFrame, JDialog, and JApplet -- are specialized components that provide a place for other Swing components to paint themselves. SwingApplication creates four commonly used Swing components: • • • • a frame, or main window (JFrame) a panel, sometimes called a pane (JPanel) a button (JButton) a label (JLabel)

The frame is a top-level container. It exists mainly to provide a place for other Swing components to paint themselves. The other commonly used top-level containers are dialogs (JDialog) and applets (JApplet). The panel is an intermediate container. Its only purpose is to simplify the positioning of the button and label. Other intermediate Swing containers, such as scroll panes (JScrollPane) and tabbed panes (JTabbedPane), typically play a more visible, interactive role in a program's GUI. The button and label are atomic components -- components that exist not to hold random Swing components, but as self-sufficient entities that present bits of information to the user. Often, atomic components also get input from the user. The Swing API provides many atomic components, including combo boxes (JComboBox), text fields (JTextField), and tables (JTable). Here is a diagram of the containment hierarchy for the window shown by SwingApplication. This diagram shows each container created or used by the program, along with the components it contains. Note that if we add a window -- a dialog, for instance -- the new window has its own component hierarchy, unattached to the hierarchy shown in this figure.

As the figure shows, even the simplest Swing program has multiple levels in its containment hierarchy. The root of the containment hierarchy is always a top-level container. The top-level container provides a place for its descendent Swing components to paint themselves.

Every top-level container indirectly contains an intermediate container known as a content pane. For most programs, you don't need to know what's between a top-level container and its content pane. As a rule, the content pane contains, directly or indirectly, all of the visible components in the window's GUI. The big exception to the rule is that if the top-level container has a menu bar, then by convention the menu bar goes in a special place outside of the content pane.


With the exception of top-level containers, all Swing components whose names begin with "J" descend from the JComponent class. For example, JPanel, JScrollPane, JButton, and JTable all inherit from JComponent. However, JFrame doesn't because it implements a top-level container. Note: A few Swing components aren't top-level containers and yet don't inherit from JComponent. The one you're most likely to need is the Box.Filler class, which is a non-painting component designed for use with BoxLayout . The Box.Filler class doesn't inherit from JComponent because it is so specialized that it needs no JComponent features, and because it is instantiated so often that it should be as small and fast as possible. The JComponent class extends the Container class, which itself extends Component . The Component class includes everything from providing layout hints to supporting painting and events. The Container class has support for adding components to the container and laying them out. This section's API tables summarize the most often used methods of Component and Container. Information about how to use the methods is scattered throughout this trail. JComponent Features The JComponent class provides the following functionality to its descendants: • • • • • • • • • Tool tips By specifying a string with the setToolTipText method, you can provide help to users of a component. When the cursor pauses over the component, the specified string is displayed in a small window that appears near the component. Borders The setBorder method allows you to specify the border that a component displays around its edges. Tool tips Borders Keyboard-generated actions Application-wide pluggable look and feel Properties Support for layout Support for accessibility Double buffering Methods to increase efficiency

Keyboard-generated actions Using the registerKeyboardAction method, you can enable the user to use the keyboard, instead of the mouse, to operate the GUI. Note: Some classes provide convenience methods for keyboard actions. For example, AbstractButton provides setMnemonic, which lets you specify the key that, in combination with a look-and-feel-specific modifier key, causes the button's action to be performed. The combination of character and modifier keys that the user must press to start an action is represented by a KeyStroke object. The resulting action event must be handled by an action listener . Each keyboard action works under exactly one of three conditions: only when the actual component has the focus, only when the component or one of its containers has the focus, or any time that anything in the component's window has the focus. Application-wide pluggable look and feel Behind the scenes, each JComponent object has a corresponding ComponentUI object that performs all the drawing, event handling, size determination, and so on for that JComponent. Exactly which ComponentUI object is used depends on the current look and feel, which you can set using the UIManager.setLookAndFeel method. Properties You can associate one or more properties (name/object pairs) with any JComponent. For example, a layout manager might use properties to associate a constraints object with each JComponent it manages. You put and get properties using the putClientProperty and getClientProperty methods. Support for layout Although the Component class provides layout hint methods such as getPreferredSize and getAlignmentX, it doesn't provide any way to set these layout hints, short of creating a subclass and overriding the methods. To give you another way to set layout hints, the JComponent class adds setter methods -- setPreferredSize, setMinimumSize, setMaximumSize, setAlignmentX, and setAlignmentY. See Layout Management for more information. Support for accessibility The JComponent class provides API and basic functionality to help assistive technologies such as screen readers get information from Swing components, . Double buffering Double buffering smooths on-screen painting. Methods to increase efficiency JComponent has a few methods that provide more efficient ways to get information than the JDK 1.1 API allowed. The methods include getX and getY, which you can use instead of getLocation; and getWidth and getHeight, which you can use instead of getSize. It also adds one-argument forms of getBounds, getLocation, and getSize for which you specify the object to be modified and returned, letting you avoid unnecessary object creation. These methods have been added to Component for Java 2 (JDK 1.2).

Top Level Containers in Swing

To appear onscreen, every GUI component must be part of a containment hierarchy. Each containment hierarchy has a top-level container as its root. Each top-level container has a content pane that, generally speaking, contains the visible components in that top-level container's GUI. You can optionally add a menu bar to a top-level container. The menu bar is positioned within the top-level container, but outside the content pane. Here's a picture of a frame created by an application. The frame contains an empty cyan menu bar and, in the frame's content pane, a large yellow label.

Top-Level Containers and Containment Hierarchies Each program that uses Swing components has at least one top-level container. This top-level container is the root of a containment hierarchy -- the hierarchy that contains all of the Swing components that appear inside the top-level container. As a rule, a standalone application with a Swing-based GUI has at least one containment hierarchy with a JFrame as its root. For example, if an application has one main window and two dialogs, then the application has three containment hierarchies, and thus three top-level containers. One containment hierarchy has a JFrame as its root, and each of the other two has a JDialog object as its root. A Swing-based applet has at least one containment hierarchy, exactly one of which is rooted by a JApplet object. For example, an applet that brings up a dialog has two containment hierarchies. The components in the browser window are in a containment hierarchy rooted by a JApplet object. The dialog has a containment hierarchy rooted by a JDialog object. Adding Components to the Content Pane Here's the code that the preceding example uses to get a frame's content pane and add the yellow label to it:

frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); As the code shows, you find the content pane of a top-level container by calling the getContentPane method. The default content pane is a simple intermediate container that inherits from JComponent, and that uses a BorderLayout as its layout manager. It's easy to customize the content pane -- setting the layout manager or adding a border, for example. However, there is one tiny gotcha. The getContentPane method returns a Container object, not a JComponent object. This means that if you want to take advantage of the content pane's JComponent features, you need to either typecast the return value or create your own component to be the content pane. Our examples generally take the second approach, since it's a little cleaner. Another approach we sometimes take is to simply add a customized component to the content pane, covering the content pane completely. If you create your own content pane, make sure it's opaque. A JPanel object makes a good content pane because it's simple and it's opaque, by default. Note that the default layout manager for JPanel is FlowLayout; you'll probably want to change it. To make a component the content pane, use the top-level container's setContentPane method. For example: JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); contentPane.setBorder(someBorder); contentPane.add(someComponent, BorderLayout.CENTER); contentPane.add(anotherComponent, BorderLayout.SOUTH); topLevelContainer.setContentPane(contentPane); Note: Don't use non-opaque containers such as JScrollPane, JSplitPane, and JTabbedPane as content panes. A non-opaque content pane results in messy repaints. Although you can make any Swing component opaque by invoking setOpaque(true) on it, some components don't look right when they're completely opaque. For example, tabbed panes generally let part of the underlying container show through, so that the tabs look non-rectangular. So an opaque tabbed pane just tends to look bad. Adding a Menu Bar All top-level containers can, in theory, have a menu bar. In practice, however, menu bars usually appear only in frames and perhaps in applets. To add a menu bar to a frame or applet, you create a JMenuBar object, populate it with menus, and then call setJMenuBar. The TopLevelDemo adds a menu bar to its frame with this code: frame.setJMenuBar(cyanMenuBar); For more information about implementing menus and menu bars, see How to Use Menus. The Root Pane Each top-level container relies on a reclusive intermediate container called the root pane. The root pane manages the content pane and the menu bar, along with a couple of other containers. You generally don't need to know about root panes to use Swing components. However, if you ever need to intercept mouse clicks or paint over multiple components, you should get acquainted with root panes. Here's a glimpse at the components that a root pane provides to a frame (and to every other toplevel container):

We've already told you about the content pane and the optional menu bar. The two other components that a root pane adds are a layered pane and a glass pane. The layered pane directly contains the menu bar and content pane, and enables Z-ordering of other components you might add. The glass pane is often used to intercept input events occurring over the top-level container, and can also be used to paint over multiple components.

Split Panes

A JSplitPane displays two components, either side by side or one on top of the other. By dragging the divider that appears between the components, the user can specify how much of the split pane's total area goes to each component. You can divide screen space among three or more components by putting split panes inside of split panes. Instead of adding the components of interest directly to a split pane, you often put each component into a scroll pane. You then put the scroll panes into the split pane. This allows the user to view any part of a component of interest, without requiring the component to take up a lot of screen space or adapt to displaying itself in varying amounts of screen space. Here's a picture of an application that uses a split pane to display a list and an image side by side:

Example: Below is the code from a example that creates and sets up the split pane. //Create a split pane with the two scroll panes in it. splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,

listScrollPane, pictureScrollPane); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(150); //Provide minimum sizes for the two components in the split pane Dimension minimumSize = new Dimension(100, 50); listScrollPane.setMinimumSize(minimumSize); pictureScrollPane.setMinimumSize(minimumSize); The constructor used by this example takes three arguments. The first indicates the split direction. The other arguments are the two components to put in the split pane. The split pane in this example is split horizontally--the two components appear side by side--as specified by the JSplitPane.HORIZONTAL_SPLIT argument to the constructor. Split pane provides one other option, specified with JSplitPane.VERTICAL_SPLIT, that places one component above the other. You can change the split direction after the split pane has been created with the setOrientation method. Two small arrows appear at the top of the divider in the example's split pane. These arrows let the user collapse (and then expand) either of the components with a single click. The current look and feel determines whether these controls appear by default. In the Java Look & Feel, they are turned off by default. The example turned them on with a call to the setOneTouchExpandable. Setting the Components in a Split Pane A program can set a split pane's two components dynamically with these four methods: • • • • setLeftComponent setRightComponent setTopComponent setBottomComponent

You can use any of these methods at any time regardless of the split pane's current split direction. Calls to setLeftComponent and setTopComponent are equivalent and set the specified component in the top or left position, depending on the split pane's current split orientation. Similarly, calls to setRightComponent and setBottomComponent are equivalent. These methods replace whatever component is already in that position with the new one. Like other containers, JSplitPane supports the add method. Split pane puts the first component added in the left or top position. The danger of using add is that you can inadvertantly call it too many times, in which case, the split pane's layout manager will throw a rather esoteric-looking exception. If you are using the add method and a split pane is already populated, you first need to remove the existing components with remove. If you put only one component in a split pane, then the divider will be stuck at the right side or the bottom of the split pane, depending on its split direction. Positioning the Divider and Restricting Its Range Use the setDividerLocation method to position the divider programmatically. You can specify the new position by pixel or by percentage. To get the current divider location specified in pixels call getDividerLocation. //Set divider at pixel 150

splitPane.setDividerLocation(150); //25% of the space goes to left/top splitPane.setDividerLocation(0.25); Another handy method, resetToPreferredSizes, sets the divider location such that the two components are at their preferred sizes. This is the initial arrangement of a split pane, unless specified otherwise. The user can set the divider location by dragging it. A split pane does not allow the user to make either of its components smaller than the component's minimum size by dragging the divider. So, you can affect the divider's range by setting the minimum sizes of the two components in the split pane. For example, to ensure that a minimum amount of each component in a split is visible at all times, set the minimum size of each component. To allow the user to drag the divider all the way to the edge of the split pane, use 0 for the minimum size. If you don't set the minimum size of the two components in a split pane, then you might end up with a split pane whose divider won't move. By default, a split pane sizes its components at their preferred size, which for many components is equal to the minimum size. This means that both components are already displayed at their minimum sizes and the divider is stuck. Most programs that put standard components in a split pane need to set the minimum sizes of the components in the split pane to a smaller size.

Tabbed Panes

With the JTabbedPane class, you can have several components (usually panels) share the same space. The user chooses which component to view by selecting the tab corresponding to the desired component. If you want similar functionality without the tab interface, you might want to use a card layout instead of a tabbed pane. To create a tabbed pane, you simply instantiate JTabbedPane, create the components you wish it to display, and then add the components to the tabbed pane using the addTab method. Here is a picture of an application that has a tabbed pane with four tabs:

A tab can have a tool tip, and it can display both text and an image. The example shows the tabs in their default position, at the top of the tabbed pane. You can change the tab position to be at the left, right, or bottom of the tabbed pane.


JColorChooser Use the JColorChooser class to provide users with a palette of colors to choose from. A color chooser is a component that you can place anywhere within your program's GUI. The JColorChooser API also makes it easy to bring up a dialog (modal or not) that contains a color chooser. The color chooser consists of everything within the box labeled Choose Text Color. This is what a standard color chooser looks like in the Java Look & Feel. It contains two parts, a tabbed pane and a preview panel. The three tabs in the tabbed pane select chooser panels. The preview panel below the tabbed pane displays the currently selected color. Here's the code from the example that creates a JColorChooser instance and adds it to the demo's window: final JLabel banner = new JLabel("Welcome to the Tutorial Zone!", JLabel.CENTER); banner.setForeground(Color.yellow); ... final JColorChooser tcc = new JColorChooser(banner.getForeground()); ... getContentPane().add(tcc, BorderLayout.CENTER); The ColorChooser constructor in the previous code snippet takes a Color argument, which specifies the chooser's initially selected color. If you don't specify the initial color, then the color chooser displays Color.white. See the Color API documentation for a list of color constants you can use. A color chooser uses an instance of ColorSelectionModel to contain and manage the current selection. The color selection model fires a change event whenever the user changes the color in the color chooser. The example program registers a change listener with the color selection model so that it can update the banner at the top of the window. The following code registers and implements the change listener: tcc.getSelectionModel().addChangeListener( new ChangeListener() { public void stateChanged(ChangeEvent e) { Color newColor = tcc.getColor(); banner.setForeground(newColor); } } ); A basic color chooser, like the one used in the example program, is sufficient for many programs. However, the color chooser API allows you to customize a color chooser by providing it with a preview panel of your own design, by adding your own chooser panels to it, or by removing existing chooser panels from the color chooser. Additionally, the JColorChooser class provides two methods that make it easy to use a color chooser within a dialog. JFileChooser

File choosers provide a GUI for navigating the file system, and then either choosing a file or directory from a list or entering a file name or directory name. To display a file chooser, you can either add an instance of JFileChooser to a container, or use the JFileChooser API to show a modal dialog that contains a file chooser. File choosers often appear within modal dialogs because file operations can be sensitive to changes within a program, A JFileChooser object only presents the GUI for choosing files. Your program is responsible for doing something with the chosen file, such as opening or saving it. Bringing up a standard open file chooser requires only two lines of code: //Create a file chooser final JFileChooser fc = new JFileChooser(); ... //In response to a button click: int returnVal = fc.showOpenDialog(aComponent); The argument to the showOpenDialog method specifies the parent component for the dialog. The parent component affects the position of the dialog and the frame that the dialog depends on. For example, the Java Look & Feel places the dialog directly over the parent component. If the parent component is in a frame, then the dialog is dependent on that frame, disappearing when the frame is iconified and reappearing when the frame is deiconified. By default, a file chooser that hasn't been shown before displays all files in the user's home directory. You can specify the file chooser's initial directory using one of JFileChooser's other constructors, or you can set the directory with the setCurrentDirectory method. The call to showOpenDialog appears in the actionPerformed method of the Open a File... button's action listener, shown in full here: public void actionPerformed(ActionEvent e) { int returnVal = fc.showOpenDialog(FileChooserDemo.this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); //this is where a real application would open the file. log.append("Opening: " + file.getName() + "." + newline); } else { log.append("Open command cancelled by user." + newline); } } The showOpenDialog methods return an integer that indicates whether the user selected a file. The value returned is either CANCEL_OPTION or APPROVE_OPTION, both constants defined by JFileChooser. Use the return value to determine whether to perform the required operation. To get the chosen file, call getSelectedFile on the file chooser. This method returns an instance of File . The example gets the name of the file and uses it in the log message. You can call other methods on the File object, such as getPath, isDirectory, or exists to get information about the file. You can also call other methods such as delete and rename to change the file in some way. Of course, you might also want to open or save the file using one of the reader or writer classes provided by the JDK. See Reading and Writing (but no 'rithmetic) for information about using readers and writers to read and write data to the file system.

The example program uses the same instance of JFileChooser to display a standard save file chooser. This time the program calls showSaveDialog: int returnVal = fc.showSaveDialog(FileChooserDemo.this); By using the same file chooser instance to display its open and save file choosers, the program reaps these benefits: 1. The chooser remembers the current directory between uses so the open and save versions automatically share the same current directory.

2. You have to customize only one file chooser, and the customizations apply to both the open and save versions of it.

Progress Bars

Sometimes a task running within a program might take a while to complete. A user-friendly program provides some indication to the user about how long the task might take and how much work has already been done. Swing provides three classes to help you create GUIs that monitor and display the progress of a long-running task: JProgressBar A visible component to graphically display how much of a total task has completed. ProgressMonitor Not a visible component. Instead, an instance of this class monitors the progress of a task and pops up a dialog if necessary. Here's a picture of a small demo application that uses a progress bar to measure the progress of a task that runs in its own thread:

Below is the code that creates and sets up the progress bar: //Where member variables are declared: JProgressBar progressBar; // the constructor for the demo's frame:

progressBar = new JProgressBar(0, task.getLengthOfTask()); progressBar.setValue(0); progressBar.setStringPainted(true); The constructor that creates the progress bar sets the progress bar's minimum and maximum values. You can also set these values with setMinimum and setMaximum. The minimum and maximum values used in this program are 0 and the length of the task, which is typical of many programs and tasks. However, a progress bar's minimum and maximum values can be any value, even negative. The code snippet also sets the progress bar's current value to 0. The call to setStringPainted causes the progress bar to display, within its bounds, a textual indication of the percentage of the task that has completed. By default, the progress bar displays the value returned by its getPercentComplete method formatted as a percent, such as 33%. Alternatively, you can replace the default with a different string by calling setString. For example, if (/*...half way done...*/) progressBar.setString("Half way there!"); You start this example's task by clicking the Start button. Once the task has begun, a timer (an instance of the Timer class) fires an action event every second. Here's the ActionPerformed method of the timer's action listener: public void actionPerformed(ActionEvent evt) { progressBar.setValue(task.getCurrent()); taskOutput.append(task.getMessage() + newline); taskOutput.setCaretPosition(taskOutput.getDocument().getLength()); if (task.done()) { Toolkit.getDefaultToolkit().beep(); timer.stop(); startButton.setEnabled(true); progressBar.setValue(progressBar.getMinimum()); } } The bold line of code gets the amount of work completed by the task and updates the progress bar with that value. So this example's progress bar measures the progress made by the task each second, not the elapsed time. The rest of the code appends a message to the output log (a text area named taskOutput) and, if the task is done, turns the timer off and resets the other controls. How to Use Progress Monitors

A progress monitor cannot be used again, so a new one must be created each time a new task is started. This program creates a progress monitor each time the user starts a new task with the Start button. Here's the statement that creates the progress monitor: progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this, "Running a Long Task", "", 0, task.getLengthOfTask()); This code uses ProgressMonitor's only constructor to create the monitor and initialize several arguments: • • • The first argument provides the parent component to the dialog popped up by the progress monitor. The second argument is a string that describes the nature of the task being monitored. This string is displayed on the dialog. The third argument is another string that provides a changeable status note. The example uses an empty string to indicate that the dialog should make space for a changeable status note, but that the note is initially empty. If you provide null for this argument, the note is omitted from the dialog. The example updates the note each time the timer fires an action event. It updates the monitor's current value at the same time: progressMonitor.setNote(task.getMessage()); progressMonitor.setProgress(task.getCurrent()); The last two arguments provide the minimum and maximum values, respectively, for the progress bar displayed in the dialog.

• • •

After the example creates the progress monitor, it configures the monitor further: progressMonitor.setProgress(0); progressMonitor.setMillisToDecideToPopup(2 * ONE_SECOND); The first line sets the current position of the progress bar on the dialog. The second tells the progress monitor to wait two seconds before deciding whether to bring up a dialog. If, after two seconds, the progress monitor's progress is less than its maximum, the monitor will bring up the dialog. By the simple fact that this example uses a progress monitor, it adds a feature that wasn't present in the version of the program that uses a progress bar. The user can cancel the task by clicking the Cancel button on the dialog. Here's the code in the example that checks to see if the user canceled the task or if the task exited normally: if (progressMonitor.isCanceled() || task.done()) { progressMonitor.close(); task.stop(); Toolkit.getDefaultToolkit().beep(); timer.stop(); startButton.setEnabled(true); } Note that the progress monitor doesn't itself cancel the task. It provides the GUI and API to allow the program to do so easily. Deciding Whether to Use a Progress Bar or a Progress Monitor Use a progress bar if:

• • •

You want more control over the configuration of the progress bar. If you are working directly with a progress bar, you can make it display vertically, you can provide a string for it to display, you can register change listeners on it, and you can provide it with a bounded range model to control the progress bar's minimum, maximum, and current values. The program needs to display other components along with the progress bar. You need more than one progress bar. With some tasks, you need to monitor more than one parameter. For example, an installation program might monitor disk space usage in addition to how many files have been successfully installed. You need to reuse the progress bar. A progress bar can be reused; a progress monitor cannot. Once the progress monitor has decided to display a dialog (or not), the progress monitor cannot do it again.

Use a progress monitor if: • • • • You want an easy way to display progress in a dialog. The running task is secondary and the user might not be interested in the progress of the task. Progress monitor provides a way for the user to dismiss the dialog while the task is still running. The task can be cancelled. Progress monitor provides a GUI for the user to cancel the task. All you have to do is call progress monitor's isCanceled method to find out if the user pressed the Cancel button. Your task displays a short message periodically while running. The progress monitor dialog provides the setNote method so that the task can provide further information about what it's doing. For example, an installation task might report the name of each file as it's installed. The task might not take a long time to complete. You decide at what point a running task is taking long enough to warrant letting the user know about it. Progress monitor won't pop up a dialog if the task completes within the timeframe you set.


Use a JSlider to let the user enter a numeric value bounded by a minimum and maximum value. By using a slider instead of a text field, you eliminate input errors. Here's a picture of an application that uses a slider to control animation speed:

Below is the code that creates the slider. JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL, 0, 30, FPS_INIT); framesPerSecond.addChangeListener(new SliderListener()); framesPerSecond.setMajorTickSpacing(10); framesPerSecond.setMinorTickSpacing(1); framesPerSecond.setPaintTicks(true); framesPerSecond.setPaintLabels(true); framesPerSecond.setBorder(BorderFactory.createEmptyBorder(0,0,10,0)); ... //add the slider to the content pane contentPane.add(framesPerSecond); By default, spacing for major and minor tick marks is zero. To see tick marks, you must explicitly set the spacing for either major or minor tick marks (or both) to a non-zero value and call setPaintTicks(true). Just calling setPaintTicks(true) is not enough. To display standard, numeric labels at major tick mark locations, set the major tick spacing, then call setPaintLabels(true). When you move the slider's knob, the stateChanged method of the slider's ChangeListener is called. Here is the code for this example's change listener: class SliderListener implements ChangeListener { public void stateChanged(ChangeEvent e) { JSlider source = (JSlider)e.getSource(); if (!source.getValueIsAdjusting()) { int fps = (int)source.getValue(); if (fps == 0) { if (!frozen) stopAnimation(); } else { delay = 1000 / fps; timer.setDelay(delay); timer.setInitialDelay(delay * 10); if (frozen) startAnimation();

} } } } Notice that our stateChanged method changes the animation speed only if getValueIsAdjusting returns false. Many change events are fired as the user moves the slider knob. This program is interested only in the final result of the user's action.

Tables and Trees

With the JTable class you can display tables of data, optionally allowing the user to edit the data. JTable doesn't contain or cache data; it's simply a view of your data. Here's a picture of a typical table displayed within a scroll pane:

JTree With the JTree class, you can display hierarchical data. A JTree object doesn't actually contain your data; it simply provides a view of the data. Like any non-trivial Swing component, the tree gets data by querying its data model. Here's a picture of a tree:

As the preceding figure shows, JTree displays its data vertically. Each row displayed by the tree contains exactly one item of data, which is called a node. Every tree has a root node from which all nodes descend. By default, the tree displays the root node, but you can decree otherwise. A node can either have children or not. We refer to nodes that can have children -- whether or not they currently have children -- as branch nodes. Nodes that can't have children are leaf nodes. Branch nodes can have any number of children. Typically, the user can expand and collapse branch nodes -- making their children visible or invisible -- by clicking them. By default, all branch nodes except the root node start out collapsed.

Box Layout

The Swing packages include a general purpose layout manager named BoxLayout . BoxLayout either stacks its components on top of each other (with the first component at the top) or places them in a tight row from left to right -- your choice. You might think of it as a full-featured version of FlowLayout. Here is an applet that demonstrates using BoxLayout to display a centered column of components:

This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window. By creating one or more lightweight containers that use BoxLayout, you can achieve some layouts for which the more complex GridBagLayout is often used. BoxLayout is also useful in some situations where you might consider using GridLayout or BorderLayout. One big difference between BoxLayout and the existing AWT layout managers is that BoxLayout respects each component's maximum size and X/Y alignment. We'll discuss that later. The following figure shows a GUI that uses two instances of BoxLayout. In the top part of the GUI, a top-to-bottom box layout places a label above a scroll pane. In the bottom part of the GUI, a left-to-right box layout places two buttons next to each other. A BorderLayout combines the two parts of the GUI and ensures that any excess space is given to the scroll pane.

The following code, taken from , lays out the GUI. This code is in the constructor for the dialog, which is implemented as a JDialog subclass. The bold lines of code set up the box layouts and add components to them. JScrollPane listScroller = new JScrollPane(list); listScroller.setPreferredSize(new Dimension(250, 80)); listScroller.setMinimumSize(new Dimension(250, 80)); listScroller.setAlignmentX(LEFT_ALIGNMENT); ... //Lay out the label and scroll pane from top to bottom. JPanel listPane = new JPanel(); listPane.setLayout(new BoxLayout(listPane, BoxLayout.Y_AXIS)); JLabel label = new JLabel(labelText);

listPane.add(label); listPane.add(Box.createRigidArea(new Dimension(0,5))); listPane.add(listScroller); listPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); //Lay out the buttons from left to right. JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS)); buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); buttonPane.add(Box.createHorizontalGlue()); buttonPane.add(cancelButton); buttonPane.add(Box.createRigidArea(new Dimension(10, 0))); buttonPane.add(setButton); //Put everything together, using the content pane's BorderLayout. Container contentPane = getContentPane(); contentPane.add(listPane, BorderLayout.CENTER); contentPane.add(buttonPane, BorderLayout.SOUTH); The first bold line creates a top-to-bottom box layout and sets it up as the layout manager for listPane. The two arguments to the BoxLayout constructor are the container that it manages and the axis along with the components will be laid out. The next three bold lines add the label and scroll pane to the container, separating them with a rigid area -- an invisible lightweight component used to add space between components. In this case, the rigid area has no width and puts exactly 5 pixels between the label and scroll pane. Rigid areas are discussed later, in Using Invisible Components as Filler. The next chunk of bold code creates a left-to-right box layout and sets it up for the buttonPane container. Then the code adds two buttons to the container, using a rigid area to put 10 pixels between the buttons. To make the buttons be placed at the right side of their container, the first component added to the container is glue. This glue is an invisible lightweight component that grows as necessary to absorb any extra space in its container. Glue is discussed in Using Invisible Components as Filler. As an alternative to using invisible components, you can sometimes use empty borders to create space around components. For example, the preceding code snippet uses empty borders to put 10 pixels between all sides of the dialog and its contents, and between the two parts of the contents. Borders are completely independent of layout managers. They're simply how Swing components draw their edges. See How to Use Borders for more information. Box Layout Features As we said before, a BoxLayout arranges components either from top to bottom or from left to right. As it arranges components, the box layout takes the components' alignments and minimum, preferred, and maximum sizes into account. In this section, we'll talk about top-to-bottom (Y axis) layout. The same concepts apply to left-to-right layout. You simply substitute X for Y, height for width, and so on. When a BoxLayout lays out components from top to bottom, it tries to size each component at the component's preferred height. If the amount of vertical space is not ideal, the box layout tries to adjust each components' height so that the components fill the available amount of space. However, the components might not fit exactly, since BoxLayout respects each component's requested minimum and maximum heights. Any extra space appears at the bottom of the container.

A top-to-bottom box layout tries to make all of its container's components equally wide -- as wide as the largest preferred width. If the container is forced to be wider than that, then the box layout tries to make all the components as wide as the container. If the components aren't all the same width (due to restricted maximum size or to any of them having strict left or right alignment), then X alignment comes into play. The X alignments affect not only the components' positions relative to each other, but also the location of the components (as a group) within their container. The following figures illustrate alignment of components that have restricted maximum widths.

In the first figure, all three components have an X alignment of 0.0 (Component.LEFT_ALIGNMENT). This means that the components' left sides should be aligned. Furthermore, it means that all three components are positioned as far left in their container as possible. In the second figure, all three components have an X alignment of 0.5 (Component.CENTER_ALIGNMENT). This means that the components' centers should be aligned, and that the components should be positioned in the horizontal center of their container. In the third figure, the components have an X alignment of 1.0 (Component.RIGHT_ALIGNMENT). You can guess what that means for the components' alignment and position relative to their container. You might be wondering what happens when the components have both restricted maximum sizes and different X alignments. The next figure shows an example of this:

As you can see, the left side of the component with an X alignment of 0.0 (Component.LEFT_ALIGNMENT) is aligned with the center of the component that has the 0.5 X alignment (Component.CENTER_ALIGNMENT), which is aligned with the right side of the component that has an X alignment of 1.0 (Component.RIGHT_ALIGNMENT). Mixed alignments like this are further discussed in Fixing Alignment Problems.

What if none of the components has a maximum width? Well, if all the components have identical X alignment, then all components are made as wide as their container. If the X alignments are different, then any component with an X alignment of 0.0 (left) or 1.0 (right) will be smaller. All components with an intermediate X alignment (such as center) will be as wide as their container. Here are two examples:

Card Layout

Here's an applet that shows a CardLayout

in action.

This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window. As the preceding applet shows, the CardLayout class helps you manage two or more components (usually JPanel instances) that share the same display space. Another way to accomplish the same thing is to use a tabbed pane . Here's the tabbed pane version of the preceding applet:

This is a picture of the applet's GUI. To run the applet, click the picture. The applet will appear in a new browser window. Because a tabbed pane provides a GUI, using a tabbed pane is simpler than using CardLayout. For example, reimplementing the preceding applet to use a tabbed pane results in a program with 12 fewer lines of code. You can see the program's code in . The CardLayout version of the program is in .

Conceptually, each component a CardLayout manages is like a playing card or trading card in a stack, where only the top card is visible at any time. You can choose the card that's showing in any of the following ways: • • • By asking for either the first or last card, in the order it was added to the container. By flipping through the deck backwards or forwards. By specifying a card with a specific name. This is the scheme the example program uses. Specifically, the user can choose a card (component) by selecting it by name from a pop-up list of choices.

The following code creates the CardLayout and the components it manages. The program runs either within an applet, with the help of AppletButton , or as an application.) //Where instance variables are declared: JPanel cards; final static String BUTTONPANEL = "JPanel with JButtons"; final static String TEXTPANEL = "JPanel with JTextField"; //Where the container is initialized: cards = new JPanel(); cards.setLayout(new CardLayout()); ...//Create a Panel named p1. Put buttons in it. ...//Create a Panel named p2. Put a text field in it. cards.add(p1, BUTTONPANEL); cards.add(p2, TEXTPANEL); When you add a component to a container that a CardLayout manages, you must specify a string that identifies the component being added. For example, in this example, the first panel has the string "JPanel with JButtons", and the second panel has the string "JPanel with JTextField". In this example, those strings are also used in the combo box. To choose which component a CardLayout shows, you need some additional code. Here's how the example program does this: //Where the container is initialized: ... //Put the JComboBox in a JPanel to get a nicer look. String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL }; JPanel cbp = new JPanel(); JComboBox c = new JComboBox(comboBoxItems); c.setEditable(false); c.addItemListener(this); cbp.add(c); contentPane.add(cbp, BorderLayout.NORTH); ... contentPane.add(cards, BorderLayout.CENTER); ... public void itemStateChanged(ItemEvent evt) { CardLayout cl = (CardLayout)(cards.getLayout());, (String)evt.getItem()); }

This example shows that you can use the CardLayout show method to set the currently showing component. The first argument to the show method is the container the CardLayout controls, that is, the container of the components the CardLayout manages. The second argument is the string that identifies the component to show. This string is the same as was used when adding the component to the container. The CardLayout API The following CardLayout methods let you choose a component. For each method, the first argument is the container for which the CardLayout is the layout manager (the container of the cards the CardLayout controls). void first(Container) void next(Container) void previous(Container) void last(Container) void show(Container, String) Examples that Use CardLayout Only one example in this trail uses CardLayout: CardWindow. Generally, our examples use tabbed panes instead of CardLayout, since tabbed panes conveniently provide a nice GUI for the same functionality.

2D Graphics

The Java 2D API enables you to easily • • • • Draw lines of any thickness Fill shapes with gradients and textures Move, rotate, scale, and shear text and graphics Composite overlapping text and graphics

For example, you could use the Java 2D API to display complex charts and graphs that use various line and fill styles to distinguish sets of data, like those shown in the following figure.

The Java 2D API also enables you to store and to manipulate image data--for example, you can easily perform image-filter operations, such as blur and sharpen, as shown in the following figure.

The Java 2D API introduced in JDK 1.2 provides enhanced two-dimensional graphics, text, and imaging capabilities for Java programs through extensions to the Abstract Windowing Toolkit

(AWT). This comprehensive rendering package supports line art, text, and images in a flexible, full-featured framework for developing richer user interfaces, sophisticated drawing programs and image editors. The Java 2D API provides • • • • • • JInternalFrame A lightweight object that provides many of the features of a native frame, including dragging, closing, becoming an icon, resizing, title display, and support for a menu bar. Generally, you add JInternalFrames to a JDesktopPane. The UI delegates the look-and-feel-specific actions to the DesktopManager object maintained by the JDesktopPane. The JInternalFrame content pane is where you add child components. So, to create a JInternalFrame that has a number of buttons arranged with the content pane's default BorderLayout object, you might do something like this: JComponent c = (JComponent) internalFrame.getContentPane(); c.add(new JButton(), BorderLayout.NORTH); c.add(new JButton(), BorderLayout.CENTER); The content pane is actually managed by an instance of JRootPane, which also manages a layout pane, glass pane, and optional menu bar for the internal frame JRootPane A uniform rendering model for display devices and printers A wide range of geometric primitives, such as curves, rectangles, and ellipses and a mechanism for rendering virtually any geometric shape Mechanisms for performing hit detection on shapes, text, and images A compositing model that provides control over how overlapping objects are rendered Enhanced color support that facilitates color management Support for printing complex documents

A lightweight container used behind the scenes by JFrame, JDialog, JWindow, JApplet, and JInternalFrame.

The "heavyweight" components (those that delegate to a peer, or native component on the host system) are shown with a darker, heavier box. The four heavyweight JFC/Swing containers (JFrame, JDialog, JWindow, and JApplet) are shown in relation to the AWT classes they extend. These four components are the only heavyweight containers in the Swing library. The lightweight container, JRootPane, is also shown. All five of these JFC/Swing containers implement the RootPaneContainer interface, and they all delegate their operations to a JRootPane (shown with a little "handle" on top). Note: The JComponent method getRootPane can be used to obtain the JRootPane that contains a given component. To add components to the JRootPane (other than the optional menu bar), you add the object to the contentPane of the JRootPane, like this: rootPane.getContentPane().add(child); The same principle holds true for setting layout managers, removing components, listing children, etc. All these methods are invoked on the contentPane instead of on the JRootPane. Note: The default layout manager for the contentPane is a BorderLayout manager. However, the JRootPane uses a custom LayoutManager. So, when you want to change the layout manager for the components you added to a JRootPane, be sure to use code like this: JOptionPane

JOptionPane makes it easy to pop up a standard dialog box that prompts users for a value or informs them of something. While the JOptionPane class may appear complex because of the large number of methods, almost all uses of this class are one-line calls to one of the static showXxxDialog methods shown below: showConfirmDialog Asks a confirming question, like yes/no/cancel. showInputDialog Prompt for some input. showMessageDialog Tell the user about something that has happened. showOptionDialog The Grand Unification of the above three. All dialogs are modal. Each showXxxDialog method blocks the current thread until the user's interaction is complete.