import java.awt.event.

Download Report

Transcript import java.awt.event.

Events
●
Anything that happens in a GUI is an event. For
example:
–
User clicks a button, presses return when typing text,
or chooses a menu item (ActionEvent)
–
Mouse button is clicked or released, or mouse cursor
moves into a component (MouseEvent)
–
User changes an object's text (TextEvent)
–
A window receives focus, is closed, or iconified
(WindowEvent)
–
and many more
Event Objects
●
●
Each event is represented by an object that:
–
gives information about the event, and
–
identifies the event source
An event source is typically a component, but
other kinds of objects can be sources as well
Event Object Hierarchy (Partial)
Object
EventObject
AWTEvent
ActionEvent
TextEvent
ComponentEvent
WindowEvent
InputEvent
MouseEvent
Listeners
●
●
●
In order to respond to an event, an object must be
notified when the event occurs
In order to be notified, the object must:
–
be registered as an event listener on the appropriate
event source, and
–
implement the appropriate listener interface
Recall: an interface is a set of methods that must
be defined by any class that implements it
Event Listener Interface Hierarchy
(Partial)
EventListener
ActionListener
TestListener
MouseListener
WindowListener
Note correspondence to event objects.
ActionEvent and ActionListener
Button
ActionEvent
ActionListener
The ActionListener interface has just one method:
public void actionPerformed(ActionEvent e) {
<code to execute when an action occurs>
}
Any class that implements the ActionListener
interface must define the actionPerformed method.
Example
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
ListenerTest test = new ListenerTest();
}
}
public class ListenerTest {
JFrame frame;
Container contentPane;
JButton button;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
contentPane = frame.getContentPane();
button = new JButton("EXIT");
contentPane.add(button, BorderLayout.CENTER);
frame.setVisible(true);
}
Event Handling
●
●
●
The previous example will put button in a
frame, but it will not respond to any clicks yet
In order to handle an ActionEvent, the
button must add an ActionListener object
We make the ListenerTest class into an
action listener by having it implement the
ActionListener interface:
●
●
●
declare that it does so with an implements clause, and
define the required actionPerformed method
What ActionListener object should be
added to button?
Modified Example
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ListenerTest implements ActionListener {
JFrame frame;
Container contentPane;
JButton button;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
contentPane = frame.getContentPane();
button = new JButton("EXIT");
button.addActionListener(this);
contentPane.add(button, BorderLayout.CENTER);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
frame.dispose();
System.exit(0);
}
Notes on the Example
●
●
●
It is a good idea to dispose any top-level
Swing window object when you are done with it
Why? Because these objects all extend
heavyweight AWT windows which:
–
are allocated by the O.S. and not by Java
–
might take graphics card memory that is not
automatically given back when Java program exits
I created a couple of dozen JFrames under KDE
and exited without disposing:
–
eventually crashed the JVM
Notes on the Example (cont'd)
●
●
●
●
System.exit(0) signals a normal exit
java.awt and java.awt.event are
separate packages; anytime you do event
handling you must import the latter
Since the ListenerTest class implements the
ActionListener interface, any instance of it
can be added to button, including this
Other methods of the form addXXXListener
are available where XXX signifies other types of
events
Another Approach
●
●
●
●
The button could add any appropriate
ActionListener, not just this
We could, for example, define another class, say,
MyActionListener, that implements the
ActionListener interface
Then we could create an object of type
MyActionListener and add it to the button
Then the ListenerTest class itself would not
have to implement the ActionListener
interface
The MyActionListener Class
import java.awt.event.*;
public class MyActionListener
implements ActionListener {
JFrame frame;
public MyActionListener(JFrame f) {
frame = f;
}
public void actionPerformed(ActionEvent e) {
frame.dispose();
System.exit(0);
}
}
Modified ListenerTest Class
import java.awt.*;
import javax.swing.*;
// java.awt.event.* no longer
// necessary
public class ListenerTest { // no longer implements
// ActionListener
JFrame frame;
Container contentPane;
JButton button;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
contentPane = frame.getContentPane();
button = new JButton("EXIT");
MyActionListener al = new MyActionListener(frame);
button.addActionListener(al);
contentPane.add(button, BorderLayout.CENTER);
frame.setVisible(true);
}
}
Anonymous Classes
●
●
●
The MyActionListener class is only used to
make one instance
In such cases an alternative is to define an
unnamed (anonymous) class ``on the fly'' in the
one place where it is used
Java allows the following construction to create
an instance of an anonymous class that
implements the ActionListener interface:
new ActionListener() {
public void actionPerformed(ActionEvent e) {
<code to execute when the event occurs>
}
}
Another Modified ListenerTest
Class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// reinstated
public class ListenerTest {
JFrame frame;
Container contentPane;
JButton button;
public ListenerTest() { // still does not need implements
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
contentPane = frame.getContentPane();
button = new JButton("EXIT");
ActionListener al =
new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose();
System.exit(0);
}
};
button.addActionListener(al);
contentPane.add(button, BorderLayout.CENTER);
frame.setVisible(true);
}
Anonymous Objects
●
●
Not only is the constructor for the anonymous
class used only once, but the one object al that is
created is used only once
So we can simplify matters further by making this
object anonymous also:
...
button = new JButton("EXIT");
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.dispose();
System.exit(0);
}
});
contentPane.add(button, BorderLayout.CENTER);
...
WindowEvents and
WindowListeners
●
●
Window events: opening, closing, activating
(receiving focus), deactivating, iconifying, and
deiconifying
WindowListener interface methods:
–
–
–
–
–
–
–
void
void
void
void
void
void
void
windowOpened(WindowEvent e)
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
windowIconified(WindowEvent e)
windowDeiconified(WindowEvent e)
Window Event Example
import java.awt.*;
import javax.swing.*;
public class ListenerTest {
JFrame frame;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
frame.setVisible(true);
}
}
We would like to add a WindowListener to
frame that will cause the JVM to exit when the
window is closed.
Adding a Window Listener
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ListenerTest {
JFrame frame;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
public void windowClosed(WindowEvent e) {} //do nothing
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
});
}
Adapter Classes
●
●
●
●
When you implement an interface, you are
required to define all interface methods, even if
you are interested in one or two.
Those you are not interested in still have to be
defined, even if they do nothing
The task of defining interface methods to do
nothing is done for you through abstract adapter
classes
If you extend an adapter class, you only have to
define the method(s) you care about; the rest do
nothing by default
Adapter Class Hierarchy (Partial)
Object
WindowAdapter
Implements
WindowListener
MouseAdapter
Implements
MouseListener
FocusAdapter
Implements
FocusListener
Using a Window Adapter
public class ListenerTest {
JFrame frame;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
}
}
Anonymous Classes Again
●
●
●
●
In the previous example the anonymous class
defined is an extension of the abstract
WindowAdapter class
In the example before that, the anonymous class
defined is an implementation of the
WindowListener interface
In both cases, the new creates an instance of the
anonymous class
The compiler creates a separate bytecode file for
each anonymous class of the form
<classname>$<n>.class
–
for example, ListenerTest$1.class
Text Fields and Listeners
●
For one-line text input, use JTextField
●
For multiple-line text, use JTextArea
●
Both extend the JTextComponent class
Text Field Example
public class ListenerTest {
JFrame frame;
JTextField textField;
Container contentPane;
public ListenerTest() {
frame = new JFrame("Test Frame");
frame.setSize(new Dimension(300,200));
frame.setLocation(100,100);
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
System.exit(0);
}
});
textField = new JTextField();
contentPane = frame.getContentPane();
contentPane.add(textField, BorderLayout.CENTER);
frame.setVisible(true);
}
}
Output
This field has had some text entering and editing done.
Note that the field fills the BorderLayout frame.