Swing Event Model

Download Report

Transcript Swing Event Model

MIT AITI 2004
Swing Event Model
Lecture 17
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?
package swinglab;
ClickReporter
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
notifies ClickCounter
JButton
actionPerformed
ClickCounter
• ClickCounter tells
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
else if (op.equals(Calc.SUB_OP)) ans
else if (op.equals(Calc.MUL_OP)) ans
else
ans
=
=
=
=
answerLabel.setText("Answer: " + ans);
pack();
}
n1
n1
n1
n1
+
*
/
n2;
n2;
n2;
n2;
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
else if (op.equals(Calc.SUB_OP)) ans
else if (op.equals(Calc.MUL_OP)) ans
else
ans
=
=
=
=
answerLabel.setText("Answer: " + ans);
}
n1
n1
n1
n1
+
*
/
n2;
n2;
n2;
n2;