Introduction to Swing
Lecture Summary
●
Over the next 2 lectures, we will
introduce you to the techniques
necessary to build graphical user
interfaces (GUI) for your applications.
– Learning Swing basic concepts:
components and containers, colors, layout;
– Constructing Swing interfaces;
– Using the Swing Event Model.
●
Style: Mixture of lecture and lab
WHAT IS SWING?
So far, our user interfaces have only been textual,
meaning the user sees text and writes text at the
command prompt.
Today we will learn to make our interfaces
graphical, so we can use our programs through
windows, click on buttons, etc.
Graphical User Interface (GUI)
Swing is Java's graphical user interface library
You MUST import the following packages:
import java.awt.*;
import javax.swing.*;
Swing Example
import java.awt.*;
import javax.swing.*;
public class MyTest extends JFrame {
JLabel myLabel = new JLabel("Hello, World!");
public MyTest() {
super("MyTest");
setSize(350, 100);
getContentPane().add(myLabel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
public static void main (String args[]) {
MyTest m = new MyTest();
}
}
Simple Swing Application
JFrame
• JFrame is the application window class
●
It is special; it draws the window and interacts with
the operating system
●
When a JFrame is created, an inner container called
the contentPane is automatically created
●
We don't draw graphics directly on JFrame; we draw
on the contentPane
Anatomy of a JFrame
title bar
minimize
maximize
close
The contentPane holds your
content; created automatically
when a JFrame is created
Exercise 1: Empty Frame
package swinglab;
import java.awt.*;
import javax.swing.*;
// extends keyword makes Calc a JFrame
public class Calc extends JFrame{
public Calc() {
// get the contentPane and assign it to cp
Container cp = getContentPane();
// exit program when user closes the window
setDefaultCloseOperation(EXIT_ON_CLOSE);
// sets the layout; will be covered in later slide
cp.setLayout(new FlowLayout());
// sets title to "My Funky Calculator"
setTitle("My Funky Calculator");
setSize(1000,700); // Frame has 0 default size
}
Exercise 1 continued
. . .
public static void main (String[] args){
Calc trial = new Calc();
// Frame is invisible by default
trial.setVisible(true);
// main method exits but user interface
// stays alive
}
}
Top Level Windows
●
Top Level Windows are containers that are not contained
by any other containers
●
They can be iconified or dragged and interact with the
native windowing system
●
Examples: JFrame, JDialog (not JComponents at all )
Categories of GUI classes
●
Swing has a large set of classes that inherit from a
super and abstract class JComponent
• JComponent: The base class for all Swing
components except top-level containers
●
Its subclasses present information or interact with
the user
– Examples:labels(JLabels), buttons(JButtons),
textfields(JTextField)
- Containers are some JComponents that are designed to hold
other components (no interaction with the user)
- Examples: JPanel, JScrollPane
Coordinates
●
The upper left hand corner of the screen has coordinates
(0,0)
●
Like the cartesian system, the value of x increases from
left to right (the x-axis goes from left to right)
●
However, the value of y increases from top to bottom (the
y-axis goes from top to bottom)
●
Measured in pixels (such as 640 by 480)
Frames, Panes and Panels
Colors
●
There are 13 predefined colors
●
You can access them using Color.x where x is
– orange, pink, cyan, magenta, yellow, black, blue,
white, gray, lightGray, darkGray, red, green
●
You can define your own colors
Color ugly = new Color(30,90,120);
//RGB(red-green-blue); values between 0-255;
Exercise 2: JPanels with color
●
Set the background of the contentPane to white
using
<nameofobject>.setBackground(<color>);
●
Create two JPanels in the constructor of Calc
●
Set the background color of one to orange; set the
background color of the other to yellow
●
Add the two JPanels to the contentPane using
<nameofobject>.add(<objecttobeadded>)
●
add the orange JPanel first; NOTE: the order in
which you add your objects determine the way
your program looks
Exercise 2: Answer
package swinglab;
import java.awt.*;
import javax.swing.*;
public class Calc extends JFrame{
private JPanel entryPanel;
private JPanel answerPanel;
public Calc() {
Container cp = getContentPane();
setDefaultCloseOperation(EXIT_ON_CLOSE);
cp.setBackground(Color.white);
setTitle("My Funky Calculator");
setSize(1000,700);
entryPanel = new JPanel();
entryPanel.setBackground(Color.orange);
answerPanel = new JPanel();
answerPanel.setBackground(Color.yellow);
// . . .
Exercise 2: answer continued
cp.add(entryPanel);
cp.add(answerPanel);
}
public static void main (String[] args){
Calc trial = new Calc();
trial.setVisible(true);
}
}
JLabels, JButtons, JComboBox etc
• These are subclasses of JComponent
• You create them just as you create other objects of a
class:
JLabel sign = new JLabel ("Sign");
• When created, you need to add them to the panel:
panel.add(sign);
// panel is the name of a created JPanel
Exercise 3: Adding a JComboBox
JComboBox
We want to create a JComboBox (drop-down menu):
For items in the menu:- Declare and initialize the
following above the Calc constructor
private JComboBox operation;
public static String ADD_OP = "ADDITION";
public static String SUB_OP = "SUBTRACTION";
public static String MUL_OP = "MULTIPLICATION";
public static String DIV_OP = "DIVISION";
Exercise 3 continued
In Calc Constructor:
●
Create a JComboBox:
operation = new JComboBox();
●
Add the items in the menu using addItem() :
operation.addItem(ADD_OP);
operation.addItem(SUB_OP);
operation.addItem(MUL_OP);
operation.addItem(DIV_OP);
●
Set its background to blue:
operation.setBackground(Color.blue);
●
Add the JComboBox to the orange panel:
<nameofORANGEpanel>.add(operation);
Exercise 4: Adding labels, buttons etc
JLabels
●
Declare 2 JLabels: letLabel and answerLabel
●
Create the two labels in the constructor
using their constructor that takes a String
as an argument and then set the
FOREGROUND color as follows:
letLabel: "Let's Calculate!" , green
answerLabel: "Answer" , red
●
Add:
letLabel to the ORANGE JPanel
answerLabel to the ORANGE JPanel
Exercise 4 continued
JTextFields
●
Declare 2 JTextFields: num1 and num2
●
In the Calc constructor, create the 2
JTextFields using their constructor that
takes a String and an int (for size) as
arguments:
num1:"1st Number" , 10
num2:"2nd Number", 10
●
Set their background color to lightGray
(predefined)
●
Add them to the ORANGE JPanel
Exercise 4 continued
JButtons
●
Declare 2 JButtons: calculate and quit
●
In Calc constructor, create the two JButtons using their
constructor which takes a String as an argument
– calculate: "Calculate"
– quit : "Quit"
●
Set their background color as follows:
calculate:pink
quit : create your color
HINT: first create the color then use it
Color leaf = new Color(50,100,50);
<nameofbutton>.setBackground(leaf);
●
Add the buttons to the YELLOW JPanel;
Exercise 4 continued
●
Compile and run the program.
●
Note that the order in which you add objects to the panel
determine their positions
●
Go back through the code and make sure that the objects
are added in the following order:
ORANGE JPanel: JLabel letLabel, JTextField num1, JTextField
num2, JComboBox operation, JLabel answerLabel
YELLOW JPanel: JButton calculate, JButton quit
Exercise 4: answer
package swinglab;
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class Calc extends JFrame{
private JLabel letLabel;
private JLabel answerLabel;
private JTextField num1;
private JTextField num2;
private JComboBox operation;
private JButton calculate;
private JButton quit;
private JPanel entryPanel;
private JPanel answerPanel;
static final String ADD_OP = "ADDITION";
static final String SUB_OP = "SUBTRACTION";
static final String MUL_OP = "MULTIPLICATION";
static final String DIV_OP = "DIVISION";
private static final int XSIZE = 1000;
private static final int YSIZE = 700;
public Calc() {
Container cp = getContentPane();
setDefaultCloseOperation(EXIT_ON_CLOSE);
cp.setLayout(new FlowLayout());
cp.setBackground(Color.WHITE);
setTitle("My Funky Calculator");
setSize(XSIZE,YSIZE);
entryPanel = new JPanel();
entryPanel.setBackground(Color.ORANGE);
answerPanel = new JPanel();
answerPanel.setBackground(Color.YELLOW);
letLabel = new JLabel("Let's Calculate!");
entryPanel.add(letLabel);
letLabel.setForeground(Color.GREEN);
num1 = new JTextField("1st Number", 10);
entryPanel.add(num1);
num1.setBackground(Color. LIGHT_GRAY);
num2= new JTextField("2nd Number", 10);
entryPanel.add(num2);
num2.setBackground(Color.LIGHT_GRAY);
operation = new JComboBox();
operation.addItem(ADD_OP);
operation.addItem(SUB_OP);
operation.addItem(MUL_OP);
operation.addItem(DIV_OP);
entryPanel.add(operation);
operation.setBackground(Color.BLUE);
answerLabel = new JLabel("Answer");
entryPanel.add(answerLabel);
answerLabel.setForeground(Color.red);
calculate = new JButton("Calculate");
calculate.setBackground(Color.pink);
answerPanel.add(calculate);
quit = new JButton("Quit");
answerPanel.add(quit);
Color quitter = new Color(50,100,50);
quit.setBackground(quitter);
cp.add(entryPanel);
cp.add(answerPanel);
}
public static void main(String[] args){
Calc trial = new Calc();
trial.setVisible(true);
}
}
Layout Manager
●
Layout management is the process of
determining the size and location of a
container's components.
●
Java containers do not handle their own
layout. They delegate that task to their layout
manager, an instance of another class.
●
If you do not like a container's default layout
manager, you can change it.
Container content = getContentPane();
content.setLayout( new FlowLayout() );
Layout Managers
●
Layout management proceeds bosttom up
through the containment hierarchy.
●
If a container encloses another container, the
enclosing container can not position the inner
container nor size itself until it knows how big the
inner container needs to be.
●
And the inner container can not size itself until it
queries its contents
●
Swing provides 6 Layout manager classes
FlowLayout
• FlowLayout, the simplest of the managers, simply adds
components left to right until it can fit no more within
its container's width.
●
It then starts a second line of components, fills that,
starts a third, etc.
●
Each line is centered in the container
• FlowLayout respects each component's preferred size
and will use it to override a size set by setSize.
• FlowLayout is the default layout manager for JPanel
BorderLayout Zones
●
A border layout divides the container into five
regions; each region may contain only one
component
North
West Center East
South
●
BorderLayout is the default LayoutManager for the
contentpane of a JFrame
Using Layout Managers
BorderLayout
<nameofcontainer>.setLayout(new BorderLayout());
When adding components to the container:
<nameofcontainer>.add(<nameofcomponent>,BorderLayout.REGION);
where REGION is either NORTH, SOUTH, WEST,
CENTER OR EAST.
JPanel panel = new JPanel(); // default
// FlowLayout
panel.setLayout(new BorderLayout());
panel.add(button,BorderLayout.NORTH);
Using Layout Managers
FlowLayout
<nameofcontainer>.setLayout(new FlowLayout());
When adding components to the container:
<nameofcontainer>.add(<nameofcomponent>);
JPanel panel = new JPanel(); // default
// FlowLayout
//following line is redundant
panel.setLayout(new FlowLayout());
panel.add(button);
Exercise 5: Setting Layouts
●
Set the layout of the contentpane to
BorderLayout
●
Add the ORANGE panel to the north region of
the contentpane
●
Add the YELLOW panel to the south region of
the contentpane
Exercise 5: Answer
. . .
public Calc() {
Container cp = getContentPane();
setDefaultCloseOperation(EXIT_ON_CLOSE);
cp.setLayout(new BorderLayout());
cp.setBackground(Color.white);
setTitle("My Funky Calculator");
setSize(XSIZE,YSIZE);
. . .
cp.add(entryPanel, BorderLayout.NORTH);
cp.add(answerPanel,BorderLayout.SOUTH);
}
pack()
●
pack() method rearranges components such
that any unused space is not shown
●
Add pack(); to the constructor of Calc. Make it
the last statement in the constructor
●
Have you noticed a difference?
Summary
●
When creating GUI, a JFrame is used; it interacts
with the native system
●
A contentPane is automatically created when a
JFrame is created. It has 5 zones where you can add
a component (default layout is BorderLayout)
• JPanel is the workhorse of most complicated
interfaces. It is
– a good all purpose container
– the standard drawing surface
●
Swing containers have default layout managers but
you can always change them
●
Swing is HUGE! You must explore it further.
Swing Event Model
The Java Event Model
●
In the last lecture, we learned how to
construct a GUI to present information to
the user.
●
But how do GUIs interact with users? How
do applications recognize when the user
has done something?
ClickReporter
package swinglab;
import java.awt.*;
import javax.swing.*;
public class ClickReporter extends JFrame {
public ClickReporter() {
JButton myButton = new JButton("Click here");
Container cp = getContentPane();
cp.add(myButton);
setTitle("Click Printer");
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
show();
}
public static void main(String[] args) {
ClickReporter cr = new ClickReporter();
}
}
ClickPrinter Listener
package swinglab;
import java.awt.event.*;
class ClickPrinter implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Button was pressed");
}
}
Adding a Listener
public ClickReporter() {
JButton myButton = new JButton("Click here");
ClickPrinter printer = new ClickPrinter();
click.addActionListener(printer);
Container cp = getContentPane();
cp.add(myButton);
setTitle("Click Printer");
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
show();
}
ClickReporter
●
Each time you click the button a message is displayed in
a console window.
Click here
Button was pressed
Event Handling Diagram
e.g. button,
menu,
text fields
Event Handling
●
To be able to handle events in Java we need 3 things:
– event sources
– event objects
– event listeners
Event Sources
●
Event sources are components that can recognize user
action: menus, buttons, text fields etc.
●
Event sources have methods to add event listeners to them
like addActionListener
●
Event source reports on events and notifies all its listeners
Event Source
●
In our ClickReporter class we create an event source, a JButton
called myButton:
JButton myButton = new JButton("Click here");
Click here
Event Objects
●
Objects that represent a user action (e.g. mouse
click) – contain detailed information about the
event.
●
When an event happens an event source sends an
event object to its event listeners
●
EventObject is the superclass
– ActionEvent, MouseEvent,etc. are
the subclasses that we use
Event Objects
●
In our example, the event source –
JButton myButton generates an event object representing a
mouse click.
●
We are not going into details of EventObjects – we will need
them only as arguments to the method actionPerformed in
event listeners.
Event Listeners
●
Event listeners are objects that respond when an event
occurs
●
Any object , whose class implements the ActionListener
interface, can be an event listener.
●
If the event listener has been added to an event source, the
listener will be called when an event occurs on that source.
ActionListener interface
●
Look it up at the API in the package
java.awt.event:
public interface ActionListener
extends EventListener {
public void actionPerformed(ActionEvent e);
}
Event Listener
In ClickReporter class we have an event
listener – ClickPrinter object called printer:
ClickPrinter printer = new ClickPrinter();
and add this listener to our JButton click:
click.addActionListener(printer);
create an event source:
JButton myButton = new JButton("Click here");
create an event listener:
ClickPrinter printer = new ClickPrinter();
add listener to the source:
click.addActionListener(printer);
●
Add the following data fields to your ClickReporter
class:
private JLabel counterLabel;
private int counter = 0;
●
Add the following three lines to the ClickReporter
constructor:
cp.setLayout(new FlowLayout());
ClickCounter cc = new ClickCounter(this);
click.addActionListener(cc);
●
Add these lines to your constructor:
counterLabel = new JLabel(
"The number of clicks is 0");
cp.add(counterLabel);
●
Add this method to ClickReporter:
void incrementCounter(){
counterLabel.setText(
"The number of clicks is " +
(++counter));
pack();
}
In your swinglab package create ClickCounter:
package swinglab;
import java.awt.event.*;
class ClickCounter implements ActionListener {
private ClickReporter clickReporter;
ClickCounter(ClickReporter c) {
clickReporter = c;
}
public void actionPerformed(ActionEvent e){
clickReporter.incrementCounter();
}
}
ClickCounter Diagram
●
Button is pressed and JButton
notifies ClickCounter
actionPerformed
●
ClickCounter tells
ClickCounter
ClickReporter to increment
its counter
incrementCounter
ClickReporter
A Calculator Listener
package swinglab;
import java.awt.event.*;
class CalcListener implements ActionListener {
private Calc calculator;
CalcListener(Calc c) { calculator = c; }
public void actionPerformed(ActionEvent e) {
calculator.calculatePressed();
}
}
●
Add this method to Calc class:
void calculatePressed() {
double n1 = Double.parseDouble(num1.getText());
double n2 = Double.parseDouble(num2.getText());
String op = (String)operation.getSelectedItem();
double ans;
if (op.equals(Calc.ADD_OP)) ans = n1 + n2;
else if (op.equals(Calc.SUB_OP)) ans = n1 - n2;
else if (op.equals(Calc.MUL_OP)) ans = n1 * n2;
else ans = n1 / n2;
answerLabel.setText("Answer: " + ans);
pack();
}
Add the Calc Listener
●
In the Calc constructor, add an instance of
CalcListener as a listener to the calculate button
CalcListener cl = new CalcListener(this);
calculate.addActionListener(cl);
Quiz Question 1
●
Q: It's annoying to make a separate class for each
listener. If any class can implement an interface, can't
Calc implement ActionListener and listen for the events
itself?
●
A: Yes
Quiz Question 2
●
Q: Is it a good idea to have Calc be a listener for itself?
●
A: No. Calc is public, and if Calc implements ActionListener,
then any outside class can use Calc to listen for unrelated
events. Calc is only designed to handle Calc 's own events.
Uh oh . . .
●
What happens when you type letters into the
textfields and click the calculate button?
●
Exceptions are thrown!
Exception Handling
●
Catch those exceptions and display an error message window
describing the error to the user.
●
To show the error message window use the method
JOptionPane.showMessageDialog
●
Hint: the parentComponent should be the Calc object itself
Solution
void calculatePressed() {
double n1 = 0, n2 = 0;
try {
n1 = Double.parseDouble(num1.getText());
n2 = Double.parseDouble(num2.getText());
} catch(NumberFormatException e) {
JOptionPane.showMessageDialog(this,
"Must type two numbers, dummy!",
"Not Numbers!", JOptionPane.ERROR_MESSAGE);
}
String op = (String)operation.getSelectedItem();
double ans;
if (op.equals(Calc.ADD_OP)) ans = n1 + n2;
else if (op.equals(Calc.SUB_OP)) ans = n1 - n2;
else if (op.equals(Calc.MUL_OP)) ans = n1 * n2;
else ans = n1 / n2;
answerLabel.setText("Answer: " + ans);
}