Graphical User Interfaces with
Swing
"It don't mean a thing if it
ain't got that Swing"
-- Duke Ellington
We want to:
- Put windows on the screen
- Process events like mouse clicks
- Add buttons, text boxes to your applications
We will only use Swing for
GUI components - we will not use the
Abstract Window Toolkit (AWT).
We will use AWT event handling, but no AWT components.
Some Definitions and Terminology
- Container
- a GUI component that can contain other GUI components
like buttons and text fields. A top-level container is not contained in
another container. In Java top-level windows are called frames; the
Swing class is JFrame.
- Intermediate
container - content pane
- Buttons, text boxes, and other user interface
components are
not added directly to the JFrame. Instead they are added to the frame's
content
pane.
- What we will do: add buttons, etc to a JPanel, and
then add the
JPanel
to the content pane.
- Low-level
Swing Components, like JButton
- Create a button by calling the JButton
constructor.
- Add the button to the JPanel using the add() method.
- We will discuss handling button clicks later.
How to Create a GUI
So to create our first GUI we will:
- Import the necessary libraries
- Use a JFrame for our top-level container.
- Add all buttons and other low-level components to a
JPanel object, and
then add the JPanel to the content pane.
Example: Adding a panel
(instance of JPanel) to the content pane of our
frame (instance of JFrame).
JFrame frame =
new JFrame("Our First Frame");
Container
contentPane = frame.getContentPane(); // returns content pane
object for this JFrame
JPanel p = new
JPanel(); // we will add low level components like buttons to this panel
contentPane.add(p);
Two additional comments:
- A frame is not automatically closeable. If you want to
be able to
select "close" in the frame's window and kill the application, you need
to write code to do this. Handling this event will be our first venture
into event handling.
- By default frames are 0 pixels x 0 pixels. If you want
to make
the frame visible and bigger, you :
- Make it bigger by calling the setSize() method
- Make it visible by calling the setVisible() method
Event Handling - The Basics
- To write more interesting programs, we must be able to
respond to
events
such as button clicks, menu selection, key press
- Event handling using the Java AWT event model
- Operating system reports events to the program, and
program
responds (or not)
- Event
sources = buttons, scroll bars, etc.
- Event
listeners - objects that carry out a desired response to an
event. Event sources have methods that allow us to register event
listeners with them.
Different event sources produce different event objects. A button sends
ActionEvent objects, a window sends WindowEvent objects.
We will first handle making our frame closeable - we need some way of
being notified that the user is closing the frame:
- Event = window being closed.
- We will attach a listener to the frame that will close
the frame in
response to this event.
The listener we will use: an instance of a class that implements the
WindowListener
interface. The WindowListener interface contains 7
methods, and we are interested in this one:
public void
windowClosing(WindowEvent e)
We will implement this method so that the program exits when it is
executed.
Using an (anonymous) class that implements the WindowListener Interface:
To avoid implementing all 7 methods in the WindowListener interface, we
will use a class WindowAdapter
that implements this interface. The
WindowAdapter class implements all 7 methods of WindowListener
interface to do nothing - we will write a new class that extends the
WindowAdapter class and overrides the windowClosing() method.
Example
frame.addWindowListener(new
WindowAdapter()
{ // definition
of anonymous class that extends WindowAdapter
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}); //
Our anonymous inner class extends the WindowAdapter class.
Now the program terminates when the
// frame is closed.
Example: FirstGUI class
The Inheritance Hierarchy for GUI Components (in class)
-- Methods that are used to resize and reshape frames are in the
Component class and the Window class.
Example: Another GUI. This time
we will:
- Set up event handling for the button - the button label
will
indicate the number of button clicks.
- The button's constructor takes a String argument.
- Attach an event handler to the button with the
addActionListener() method.
- Use an anonymous inner class that implements the
ActionListener
interface to handle the event. Need to implement actionPerformed()
method.
Layout Management
Flow Layout
- The default layout manager for a panel: FlowLayout
- Fills a row with components, and then starts filling
a new row
- You choose how to arrange the components in a row
- Default: Center the components in the row
- Choose to align them left or right in the container
- The setLayout() method allows you to specify the layout
of a
component
Example:
Component pane = JPanel();
...
pane.setLayout(new FlowLayout(FlowLayout.LEFT)); // pass in
alignment to
// FlowLayout constructor
- Other alignment options: FlowLayout.CENTER,
FlowLayout.RIGHT
Example: GUIEx.java. Multiple
Buttons in a panel.
Example: GUIEx - edit it to use
a different alignment
Another FlowLayout constructor:
FlowLayout(int alignment, int horizontalGap, int verticalGap)
- horizontalGap = horizontal gap between components in
pixels
- verticalGap = vertical gap between components in pixels
Border Layout
- Default layout manager for the content pane of frames:
BorderLayout
- This manager allows you to choose the region in which
to place
each component: North, West, Center, East, South
Example: pane.setLayout(new
BorderLayout() );
pane.add(button, "South");
- Components around the border - components in the North,
West,
East and South regions - are placed first, and the remaining space is
occupied by the Center.
- In BorderLayout components grow to fill the available
space.
- 2nd constructor: BorderLayout(int horizontalGap, int
verticalGap)
- BorderLayout alone is not very useful - if you place a
button in
the South region, it will fill the entire South region. If you then add
another button to the South region, it will overwrite the first button.
- Take care of this problem by using multiple panels:
place several
buttons in a panel, and then add the panel to the South region. Put all
components you want in the North region on a panel, and add the panel
to the North region, etc.
Exercise: Modify
GUIEx so that
button, button2, button3 appear in the South region of the frame.
Grid Layout
- arranges all components in rows and columns like a
spreadsheet.
All cells are the same size.
- Specify the number of rows and columns in the
constructor for
grid layout:
- new GridLayout(int rows, int columns)
Example: JPanel panel = new
JPanel();
panel.setLayout(new GridLayout(2, 2));
- You can specify the vertical and horizontal gaps in the
constructor as well: panel.setLayout(new GridLayout(2, 2, 3, 3);
- So here we have a horizontalGap and verticalGap of 3
pixels.
- First add the components in the 1st row, then the 2nd
row, etc.
- Each component in the grid is stretched to fill the
entire cell
and all components have the same size.
Exercise: Write your own
program that uses a grid layout to place 2 rows of buttons in a frame,
with 2 buttons per row. Handle button clicks for each button.