You are on page 1of 40

Implementing GUIs in Java


The Java Foundation Classes (JFC) are a set of
packages encompassing the following APIs:
– Abstract Window Toolkit (AWT): native GUI
components
– Swing: lightweight GUI components
– 2D: rendering two-dimensional shapes, text, and
images
– Accessibility: allowing compatibility with, for
example, screen readers and screen magnifiers
Abstract Window Toolkit (AWT)

Provides basic UI components:
– Buttons, lists, menus, textfields, etc
– Event handling mechanism
– Clipboard and data transfer
– Image manipulation
– Font manipulation
– Graphics

Platform independence is achieved through peers,
or native GUI components
AWT Packages
java.awt Basic component functionality
java.awt.accessibility Assistive technologies
java.awt.color Colors and color spaces
java.awt.datatransfer Clipboard and data transfer support
java.awt.dnd Drag and drop
java.awt.event Event classes and listeners
java.awt.font 2D API font package
java.awt.geom 2D API geometry package
java.awt.im Input methods
java.awt.image Fundamental image manipulation classes
java.awt.peer Peer interfaces for component peers
java.awt.print 2D API support for printing
java.awt.swing Swing components
Peers and Platform Independence

The first AWT (Java 1.0) was rolled out in an
incredible 6 weeks using peers

Thus an AWT menu on the Solaris platform, for
example, actually creates a Motif menu object as
its peer

UI components that have peers are called
heavyweight because
– they are rendered in their own (opaque) windows and
thus are expensive to use,
– they must be rectangular and cannot have transparent
backgrounds, and
– they are not amenable to being subclassed
Using Peers

Native
Java Java Window
Program AWT System
Peers

A Java program creates and displays an AWT component,


which creates and displays a native component, or peer.
Lightweight Components

AWT 1.1 introduced the notion of lightweight
components which:
– are contained within a heavyweight component's
window
– do not have peers
– are rendered in their container's window rather than
one of their own
– do not incur performance penalties and can have
transparent backgrounds

Almost all Swing components are lightweight
ones that extend either java.awt.Component
or java.awt.Container
Some AWT Components
Object

Component

Container List Button

JComponent Scrollbar

Label

Canvas
AWT vs. Swing

Swing does not replace the AWT; it is built on
top of it

All 1.0 AWT components are heavyweight;
corresponding Swing components are lightweight

Swing component names begin with ``J'':
– Component (AWT) vs. JComponent (Swing)
– Button (AWT) vs. JButton (Swing)

Always use Swing components; however, since
Swing is built on top of AWT, you will need to
know some AWT methods
Some Swing Components
JComponent

AbstractButton JLabel

JMenuIte
JButton JList
m
JToggleButto
JScrollBar
n

JCheckBox

JFileChooser
JComponents

Note that JComponents are containers

JComponents do not extend their AWT
counterparts:
– For example, the JButton class is not a subclass
(direct or indirect) of Button

However, some Swing components are not
JComponents
– For example, some Swing containers are direct
subclasses of their AWT counterparts
Some AWT Containers
Container

JComponent Panel

ScrollPane

Window Applet

Dialog Frame
Swing Components That Are Not
JComponents (in red)
Container

JComponent Panel

Window ScrollPane

Dialog Frame Applet

JWindow
JDialog JFrame JApplet
Some More Swing Components That
Are JComponents
JComponent

JLayeredPane JPanel

JDesktopPane JScrollPane

JInternalFrame

JTable
JTree
Some AWT Component Methods

void setBackground(Color c)

void setForeground(Color c)

void setEnabled(boolean b)

void setVisible(boolean b)

void setFont(Font f)

void setSize(Dimension d)

void setLocation(int x, int y)

All but setSize and setLocation are overridden


by the JComponent class.
Example: A Simple Framed Window

import java.awt.*;
import javax.swing.*;

public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
frame.setVisible(true);
}

}
Notes on the Example

setSize and setLocation require
java.awt.*; the rest require javax.swing.*

The JFrame constructor argument is used as a title

The Dimension constructor takes an integer width
and height, respectively

The setLocation method takes a pair of integer
coordinates (x,y) where (0,0) is the upper left corner of
the display

The visibility of a JFrame is set to false by default
Example Output Display


This window was managed by the K Desktop
Environment (KDE)

Clicking the Close button (X) will cause the display
to be hidden, but the program will continue since no
listeners are set up yet

Can use ctl-C to kill the Java Virtual Machine
Adding Color
The java.awt.Color class has the following static
fields (data members):
– Color.black – Color.magenta
– Color.blue – Color.orange
– Color.cyan – Color.pink
– Color.darkGray – Color.red
– Color.gray – Color.white
– Color.green – Color.yellow
– Color.lightGray
Changing Background Color
import java.awt.*;
import javax.swing.*;

public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();
contentPane.setBackground(Color.red);
frame.setVisible(true);
}

}
Content Panes

Q: Why not just: frame.setBackground(Color.red); ?

A: In order to be lightweight, Swing's top-level
window objects must be built on top of a lightweight
AWT Container object introduced in version 1.1

This container is called a content pane

Swing top-level window classes:
– JWindow
– JFrame
– JApplet
– JDialog
– JInternalFrame
Adding a Label and Button
import java.awt.*;
import javax.swing.*;

public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();

JLabel label = new JLabel("HERE IS A LABEL");


contentPane.add(label, BorderLayout.NORTH);

JButton button = new JButton("BUTTON");


contentPane.add(button, BorderLayout.SOUTH);
frame.setVisible(true);
}

}
New Display

Resized
Notes on the Code

Since the frame is a top-level Swing window,
components must be added to its content pane

When components are added to a container, how
they are placed is dependent upon the container's
layout manager

The default layout manager for a JFrame is a
BorderLayout manager (described later)

When adding to a container whose layout
manager is BorderLayout, the second
parameter should be a location defined in the
BorderLayout class
Adding a List of Options
import java.awt.*;
import javax.swing.*;

public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();
JLabel label = new JLabel("HERE IS A LABEL");
contentPane.add(label, BorderLayout.NORTH);
JButton button = new JButton("BUTTON");
contentPane.add(button, BorderLayout.SOUTH);
String[] options = {"Option 1", "Option 2",
"Option 3"};
JList list = new JList(options);
contentPane.add(list, BorderLayout.CENTER);
frame.setVisible(true);
}
}
New Display

Note that "Option 3" has been selected.


Adding a Check Box and Slider
public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(400,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();
JLabel label = new JLabel("HERE IS A LABEL");
contentPane.add(label, BorderLayout.NORTH);
JButton button = new JButton("BUTTON");
contentPane.add(button, BorderLayout.SOUTH);

String[] options = {"Option 1", "Option 2", "Option 3"};


JList list = new JList(options);
contentPane.add(list, BorderLayout.CENTER);

JCheckBox cbox = new JCheckBox("Check");


contentPane.add(cbox, BorderLayout.WEST);

JSlider slider = new JSlider();


contentPane.add(slider, BorderLayout.EAST);

frame.setVisible(true);
}
}
New Display
Layout Management

A layout manager determines the location and size of
components placed into a container

Different layout managers use different algorithms for
determining size and location:
– BorderLayout: places at compass locations and center
– FlowLayout: places components in rows, left to right
– GridLayout: places in rectangular grid
– BoxLayout: places in a single row or column
Changing the Layout
public class SwingTest {

public static void main(String[] args) {


JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();

contentPane.setLayout(new FlowLayout());
JLabel label = new JLabel("HERE IS A LABEL");
JButton button = new JButton("BUTTON");
String[] options = {"Option 1", "Option 2", "Option 3"};
JList list = new JList(options);
JCheckBox cbox = new JCheckBox("Check");
JSlider slider = new JSlider();
contentPane.add(label);
contentPane.add(button);
contentPane.add(list);
contentPane.add(cbox);
contentPane.add(slider);

frame.setVisible(true);
}

}
New Display

Resized
Default Layout Managers

The default layout manager for content panes is
BorderLayout. Recall that the following
Swing components have content panes:
– JWindow
– JFrame
– JDialog
– JApplet
– JInternalFrame

The other Swing container is the JPanel, whose
default layout manager is FlowLayout.
JPanels

A JPanel object can be used for grouping
components into a container, which can then be
added to another container

The JPanel constructor with no arguments
creates a panel with a FlowLayout manager

Another JPanel constructor takes any layout
manager as an argument

A JPanel can also be used a a blank area for
drawing custom graphics
JPanel Example
JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();

JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);

JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");
JButton button3 = new JButton("BUTTON3");

JPanel panel = new JPanel();


panel.add(button1);
panel.add(button2);
panel.add(button3);

contentPane.add(label, BorderLayout.NORTH);
contentPane.add(panel, BorderLayout.CENTER);

frame.setVisible(true);
JPanel Example Output

Note use of SwingConstants.CENTER argument


in JLabel constructor.
Changing JPanel Layout
JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();

JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);

JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");
JButton button3 = new JButton("BUTTON3");

JPanel panel = new JPanel();


panel.setLayout
(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(button1);
panel.add(button2);
panel.add(button3);

contentPane.add(label, BorderLayout.NORTH);
contentPane.add(panel, BorderLayout.CENTER);
New Output


The button panel is to the west because no other
component was placed there

The BoxLayout constructor requires both the
component being laid out and either:
– BoxLayout.X_AXIS
– BoxLayout.Y_AXIS
Tweaking Layouts

Some layout constructors allow hgap and vgap,
integers specifying the number of pixels
separating components horizontally and vertically

FlowLayout allows the specification of
whether the line of components should be left-
justified, right-justified, or centered

new FlowLayout(int align)


new FlowLayout(int align, int hgap, int vgap)
new BorderLayout(int hgap, int vgap)
new GridLayout(int rows, int cols)
new GridLayout(int rows, int cols,
int hgap, int vgap)
Tweaking Example
JFrame frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
Container contentPane = frame.getContentPane();
LayoutManager lm = contentPane.getLayout();
((BorderLayout)lm).setHgap(25);

JLabel label = new JLabel("HERE ARE SOME BUTTONS",


SwingConstants.CENTER);

JButton button1 = new JButton("BUTTON1");


JButton button2 = new JButton("BUTTON2");
JButton button3 = new JButton("BUTTON3");

JPanel panel = new JPanel();


panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(button1);
panel.add(button2);
panel.add(button3);

contentPane.add(label, BorderLayout.NORTH);
contentPane.add(panel, BorderLayout.CENTER);

frame.setVisible(true);
Tweaking Example Output


The LayoutManager returned by
getLayout() is an interface type that the
BorderLayout class implements

The setHgap method we want is in the
BorderLayout class

So we must cast the LayoutManager to
BorderLayout in order to use setHgap
Sizing Hints

Layout managers often need to resize their
components to make things fit
– For example, the widths and heights of components in
a BoxLayout are adjusted according to both
preferred and maximum heights and widths

If you don't like the size of the components a
layout manager comes up with, you may have to
give sizing hints using the following methods
from the JComponent class:
– void setMinimumSize(Dimension d)
– void setPreferredSize(Dimension d)
– void setMaximumSize(Dimension d)

You might also like