You are on page 1of 76

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.

b) Support for UI containers, which can contain other embedded containers and
widgets.

c) Provision of Layout Managers whose duty is to handle the laying out of components
on Containers.

d) 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) Visual Components
b) Container Components
c) Menu Components
The fundamental visual controls in java are:

1. Label – A simple label


2. Button – A simple push button
3. Checkbox – A combination of check box and radio (option) button
4. Choice – A drop down list control
5. List – A list box
6. Scroll bar – Horizontal and Vertical Scroll bar
7. Text Field – A single line text entry field
8. Text Area – A multiple line text entry field

The fundamental Container Components in java are:

1) Frame
2) Window
3) Applet
4) Panel

The fundamental Menu Components are:

1) MenuBar
2) Menu
3) MenuItem
4) 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. setBounds Changes control shape and location


2. setSize Changes control size
3. setEnabled Sets control to active or inactive
4. setBackground Sets background color
5. getBackground Gets background color
6. isEnabled Returns boolean indicating whether currently enables
7. isVisible Returns boolean indicating whether control is visible
8. getLocation Returns the x and y location
9. setLocation Moves the control to a new location
10. requestFocus Asks system to give focus to control
11. getBackground Sets Background Color
12. getForeground Sets Foreground Color
13. setFont Sets font to font , style and size
14. getSize Returns the current size of control

The methods of the class Container are:

Sr. No Method Description

1 Component add (Component c) Adds the specified component to the end of


this container

2 Component add (Component c, int pos) Adds the specified component to this
container at the given position. Here the
number would be –1 to insert at the end

4 int getComponentCount () Gets the number of components in the


container.
5 Component getComponent (int n) Gets the specified Component

6 LayoutManager getLayout () Gets the container’s LayoutManager

7 void remove (Component c) Remove the specified Component

8 void removeAll () Removes all Components

9 void setLayout (LayoutManager m) 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(Color.blue);
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:

Frame () - Constructs a frame


Frame (String title) - Constructs a frame with appropriate 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(Color.blue);
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(Color.blue);
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:

Panel () - Creates a new Panel


Panel ( LayoutManager layout) - Creates a Panel with the specified
LayoutManager

- 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(Color.blue);
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(Color.blue);
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) code - Which is the class name of the class to be opened

b) width - The width of the applet window.

c) 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(Color.red);
f.setSize(400,400);
f.setVisible(true);

Window w = new Window(f);


w.setBackground(Color.blue);
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) BorderLayout
b) FlowLayout
c) GridLayout
d) 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.

GridbagLayout
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) FlowLayout fully honors the preferred size of any component.

b) 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) The GridLayout does not honor the preferred size of the component at all.

d) 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) Applet
b) Canvas
c) Frame
d) Panel

The paint method already has a Graphics class as its parameter and the 3 major operations
provided by the Graphics class are:

a) Selecting a Color
b) Selecting a font
c) 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) drawString ( String s, int x-cor, int y-cor);

b) drawLine(int x0, int y0, int x1, int y1);

c) drawOval(int x, int y, int width, int height) and fillOval.

d) drawRect(int x. int y, int width, int height) and fillRect

e) drawArc(int x, int y, int width, int height, int startdegree, int arcdegree) and
fillArc.

f) drawPolygon(int x[], int y[], int points) and fillPolygon

g) drawPolyline(int x[], int y[], int points)

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(Color.red);
// 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) After exposure

b) After deiconification

c) Shortly after init () method returns (only applets)

d) 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 () - Creates an empty label


Label (String t) - Creates a label with the given text string and
aligned left
Label (String t, int alignment) - Creates a label with the given text string and
the given 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 () - Creates an empty button with no label.


Button (String t) - 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”)); or by using the following statement

Button b = new Button (“First”);


add(b);

When a Button is pushed, it sends an Action Event.


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(Color.red);
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 () - creates an empty checkbox, unselected.


Checkbox (String t) - creates a checkbox with the string as a label.
Checkbox (String t - creates a checkbox that is either selected or
boolean b unselected based on whether the boolean
CheckboxGroup c) 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 () - Gets current selected check box

setSelected Checkbox () - 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:

Scrollbar () - Default vertical Scrollbar


Scrollbar (int orientation) - constructs a scroll bar with the specified
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:

TextField () - Constructs an TextField

TextField (int cols) - Constructs the TextField with specified


number of columns

TextField (String txt) - Constructs the TextField with specified Text

TextField (String t, int cols) - Constructs the TextField with specified Text and number
of columns.

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:

TextArea () - Constructs the new TextArea

TextArea ( int rows, int cols) - Constructs the TextArea with the
specified number of rows and columns.

TextArea (String text) - Constructs the TextArea with the


specified String displayed.

TextArea (String t, int rows, int cols) - Constructs the TextArea with specified
text, number of rows and columns.
- 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.show();
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(Color.red);
p1.setBackground(Color.blue);

f.add("North" , p);
f.add("South",p1);
f.setBackground(Color.green);
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. ComponentAdapter
2. ContainerAdapter
3. FocusAdapter
4. KeyAdapter
5. MouseAdapter
6. MouseMotionAdapter
7. 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 de-
selected. 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.

b) getX () which returns an int which returns the horizontal x position of the event
relative to the source component.

c) 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 Event Methods in interface Add method


ActionListener ActionEvent actionPerformed(ActionEvent) addActionListener()
AdjustmentListene AdjustmentEvent adjustmentValueChanged(AdjustmentEv addAdjustmentListener()
r ent)
ComponentListen ComponentEvent componentHidden(ComponentEvent) addComponentListener()
er 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);
d.show();
}

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);
d.show();
}
else if (ae.getSource()==mi2)
{
d = new FileDialog(f,"FirstFile",FileDialog.SAVE);
d.show();
}
}
}

//<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.

JComponent

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
• Borders
• Keyboard-generated actions
• Application-wide pluggable look and feel
• Properties
• Support for layout
• Support for accessibility
• Double buffering
• Methods to increase efficiency

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.
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 top-
level 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.

Choosers
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;

//...in 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.

Sliders

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 ListDialog.java , 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 TabWindow.java . The CardLayout
version of the program is in CardWindow.java .
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());
cl.show(cards, (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

• 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

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 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.

You might also like