Event Handling

Download Report

Transcript Event Handling

COMP201 Java Programming
Topic 9: Event Handling
Reading: Chapter 8
COMP201 Topic 9 / Slide 2
Objective and Outline

Objective:


Show how to write GUI programs that react to user actions.
Outline:

Java AWT event delegation model
– An example


The AWT event hierarchy
Individual events
– KeyEvents
– MouseEvents

Special classes and interfaces for event handling
– Adapter classes
– The Action interface
COMP201 Topic 9 / Slide 3
Java AWT event delegation model

Java automatically generates event objects when

Mouse or button clicked
Menu, checkbox, or text selected
Keyboard typed
Scrollbar adjusted

…..




It is up to the programmer to decide whether to do
anything or what to do when an event happens
COMP201 Topic 9 / Slide 4
Java AWT event delegation model

Event source:


An object that generates events
Listener:

Receives events and decides what to do
Event Object evt
Event Listener
Event Source
COMP201 Topic 9 / Slide 5
Java AWT event delegation model

Notes

A listener must be registered with an event source in order to listen
for events produced there.
– An event source can have multiple listeners and vice versa

A listener class must implement a listener interface, which decides
the response to an event.
COMP201 Topic 9 / Slide 6
Java AWT event delegation model
Event Object evt
Event Listener
Event Source
Any objects of class that implements Has to register its
own listeners
an appropriate listener interface
class Listener implements
ActionListener {
…
actionPerformed(Event evt) {…}
}
Source.addActionL
istener(Listener)
COMP201 Topic 9 / Slide 7
Java AWT event delegation model

The event handling process:

When an event occurs, event source sends event objects to all
registered listeners.

Listeners use information encapsulated in the event objects to
determine what to do.
Event Object evt
Event Listener
Event Source
COMP201 Topic 9 / Slide 8
Example

A button that beeps when clicked (Beeper.java)

Create a GUI with one button
class BeeperFrame extends JFrame
{
public BeeperFrame()
{
setSize( 300, 200);
button = new JButton("Click Me");
getContentPane().add(button,
BorderLayout.CENTER);
}
Javax.swing.JButton
private JButton button;
has five constructors
}
Java.awt.Container
Adding button directly onto
contentPane. Bad programming style.
void add(Component)
COMP201 Topic 9 / Slide 9
Example

When a button is clicked, an ActionEvent object is produced
(java.awt.event.ActionEvent).

Listener for an ActionEvent: an object of a class that implements the
ActionListener Interface

class ClickListener implements ActionListener
{
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().beep();
}
}
COMP201 Topic 9 / Slide 10
Example


Create a listener object and register it with the button:
class BeeperFrame extends JFrame
{ public BeeperFrame()
{
…
button = new JButton("Click Me");
button.addActionListener(new ClickListener());
}
}
The driver class:
public class Beeper
{ public static void main(String[] args)
{
BeeperFrame frame = new BeeperFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
} //Check out Beeper1.java (inner class)
COMP201 Topic 9 / Slide 11
Outline

Outline:

Java AWT event delegation model
– Two examples


The AWT event hierarchy
Individual events
– KeyEvents
– MouseEvents

Special classes and interfaces for event handling
– Adapter classes
– The Action interface
COMP201 Topic 9 / Slide 12
The AWT Event Hierarchy
EventObject
…….
Action
Event
Container
Event
java.util
AWTEvent
Adjustment
Event
java.awt.event
Component
Event
Item
Event
Text
Event
Input
Event
Paint
Event
Window
Event
Focus
Event
Key
Event
Swing has more event types
Programmer can create new event types
Mouse
Event
Programmer no need
to worry about paint
events
COMP201 Topic 9 / Slide 13
The AWT Event Hierarchy

11 listener interfaces in java.awt.event
ActionListener
KeyListener
AdjustmentListener
MouseListener
ComponentListener
MouseMotionListener
ContainerListener
TextListener
FocusListener
WindowListener
ItemListener
COMP201 Topic 9 / Slide 14
The AWT Event Hierarchy

Semantic Events: What user does
 ActionEvent (button click, menu selection)
 AdjustmentEvent (adjusting scroll bar)
 ItemEvent (selection from checkbox or list items)
 TextEvent (the contents of a text field or text area were
changed)

Additional events (like MenuEvent, ChangeEvent) can be
found in javax.swing.event. They are associated with
Swing components and easy to handle. Will discuss some in the
next topic.
COMP201 Topic 9 / Slide 15
The AWT Event Hierarchy

Low-Level Events: facilitate semantic events

ComponentEvent (component resized, moved, shown, or hidden)
 (A component
is a user interface elements such as button, text
field, scrollbar, panel, frame)
 ComponentEvent is the ancestor of all low-level event classes

FocusEvent (component get focus)

ContainerEvent (a component has been added or removed.
Programmers no need to worry about it)
(A container is a screen area or component that can contain
components. E.g. window, panel)
COMP201 Topic 9 / Slide 16
The AWT Event Hierarchy

Low-Level Events: facilitates semantic events




KeyEvent (key pressed or released)
MouseEvent (mouse button pressed, released, moved, or
dragged)
WindowEvent (window activated, deactivated, iconified,
deiconified, or closed)
Will discuss KeyEvent and MouseEvent
COMP201 Topic 9 / Slide 17
Last Time

AWT event delegation model

Event source:
– What are inside an event class?
– How to find out the types of events that a component generates?

Listener:
– What are inside an listener class?
COMP201 Topic 9 / Slide 18
Creating a Responsive GUI

Set up GUI


Layout various components on the contenPane of top-level container
Decide which events to handle

Begin with design objectives: Functionalities of GUI
 For each component, find out the events that it generates
– Check API of component class and look for methods addXXXXListener
 implies that the component produces events of type XXXEvent

Handle events

Write listener class
– Check API of listener interface and decide which methods to override
– Check API of event class so as to get information about events

Create listener object
 Register listener object with event source
COMP201 Topic 9 / Slide 19
Objective and Outline

Objective:


Show how to write GUI programs that react to user actions.
Outline:

Java AWT event delegation model
– An example


The AWT event hierarchy
Individual events
– KeyEvents
– MouseEvents

Special classes and interfaces for event handling
– Adapter classes
– The Action interface
COMP201 Topic 9 / Slide 20
KeyEvent

Focus


A GUI consists of many components.
Which component received keystrokes?
– The component that has focus

Focus is gained or lost in response to user actions:

A component gains focus if the user clicks the mouse inside it.

Or TAB/SHIT-TAB key can be used to traverses components which
can receive input focus
COMP201 Topic 9 / Slide 21
KeyEvent

Methods of java.awt.Component for managing focus

void requestFocus(): Moves focus to this component

boolean isFocusable(): Tells whether a component can be reached
by using TAB or SHIFT-TAB

void transferFocus(): Transfer focus to the next component in the
traversal order.
COMP201 Topic 9 / Slide 22
KeyEvent

FocusEvent is generated when a component gains
focus or loses focus. Refer to textbook for how to
handle focus events.
COMP201 Topic 9 / Slide 23
KeyEvent


Java distinguishes between characters and virtual key code
–
“A” and “a” have the same code VK_A
– There is no VK_a !!
– More examples: VK_COMMA, VK_PERIOD, VK_OPEN_BRACKET,
VK_SHIFT ...
COMP201 Topic 9 / Slide 24
KeyEvent

KeyEvent objects are generated by the component with focus when a
key is pressed or released.

Typing “a” generates three KeyEvent objects
– 2 Lower-level events
 keyPressed VK_A (Virtual key code)
 keyReleased VK_A (Virtual key code)
– One higher-level event: keyTyped “a”
 Only for keys that generate character input

Methods of java.awt.event.KeyEvent Class:

getKeyCode() to get back virtual key code.
 getKeyChar() to get back the key character
 ….
COMP201 Topic 9 / Slide 25
KeyEvent

Methods in the KeyListener Interface:



keyPressed(KeyEvent e)
(what to do when VK_A pressed?)
keyReleased(KeyEvent e)
(what to do when VK_A released?)
keyTyped(KeyEvent e)
(what to do when “a” is typed?)
e.getKeyCode() seems to give 0 within keyTyped
Will illustrate with example
COMP201 Topic 9 / Slide 26
KeyEvent

Example: Sketch.java


Move with either cursor keys or “h”, “j”, “k”, “l” keys
Move faster when SHIFT is pressed
COMP201 Topic 9 / Slide 27
KeyEvent
Setup:
public SketchPanel extends JPanel
{ public void paintComponent(Graphics g)
{ super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
// draw all lines
for (int i = 0; i < lines.size(); i++)
g2.draw((Line2D)lines.get(i));
}
public void add(int dx, int dy) ..
// add line segement last (x, y) –-- (x+dx, y+dy)
// calls repaint()
private ArrayList lines
private Point2D last; // last point
COMP201 Topic 9 / Slide 28
KeyEvent

Getting focus and register key listener
public class SketchPanel
{
public SketchPanel()
{
…
KeyHandler listener = new KeyHandler();
addKeyListener(listener);
}
public boolean isFocusable() { return true; }
…
}
..}
We need this because by default a panel
cannot get keyboard focus
COMP201 Topic 9 / Slide 29
KeyEvent

Processing cursor keys:
class KeyHandler implements KeyListener
{
public void keyPressed(KeyEvent event)
{ // set distance: whether shift is down
int d;
if (event.isShiftDown()) d = LARGE_INCREMENT;
else d = SMALL_INCREMENT;
// direction of move: what key is typed
int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) add(-d, 0);
else if (keyCode == KeyEvent.VK_RIGHT) add(d, 0);
else if (keyCode == KeyEvent.VK_UP) add(0, -d);
else if (keyCode == KeyEvent.VK_DOWN) add(0, d);
}
Note: Can also use getModifiers of InputEvent or
getKeyModifiers of KeyEvent to find out whether SHIFT is down
COMP201 Topic 9 / Slide 30
KeyEvent

Typing keys “h”. “j”, “k”, “l”:
public void keyTyped(KeyEvent event)
{ char keyChar = event.getKeyChar();
int d; // distance of move
if (Character.isUpperCase(keyChar))
{ d = LARGE_INCREMENT;
keyChar = Character.toLowerCase(keyChar);
}
else d = SMALL_INCREMENT;
// direction of move
if (keyChar == 'h') add(-d, 0);
else if (keyChar == 'l') add(d, 0);
else if (keyChar == 'k') add(0, -d);
else if (keyChar == 'j') add(0, d);
}
Note: Can also use getModifiers of InputEvent or getKeyModifiers
of KeyEvent to find out whether upper case or lower case
COMP201 Topic 9 / Slide 31
Things to Try

Delete isFocusable()

getKeyCode within keyTyped

Modify example so that event source and listener are
the same object

Make the listener class in Sketch.java an anonymous inner
class.
COMP201 Topic 9 / Slide 32
Objective and Outline

Objective:


Show how to write GUI programs that react to user actions.
Outline:

Java AWT event delegation model
– An example


The AWT event hierarchy
Individual events
– KeyEvents
– MouseEvents

Special classes and interfaces for event handling
– Adapter classes
– The Action interface
COMP201 Topic 9 / Slide 33
MouseEvent

Just want to know whether a button or menu is clicked?



No need to use mouse events explicitly.
Instead use ActionEvents generated by button or menu.
For drawing with mouse, mouse events are important.
COMP201 Topic 9 / Slide 34
MouseEvent

MouseEvent objects generated by components where mouse cursor
is located

Getting information about MouseEvents

int getX(), int getY() to get the x , y coordinates of mouse pointer.

Point getPoint() to get coordinates of mouse pointer as a Point object

int getClickCount() to get number of consecutive clicks.

int getModifiers() to find out, among other things, which mouse button is
clicked.
COMP201 Topic 9 / Slide 35
MouseEvent

Two listener interfaces

MouseListener
– mousePressed(MouseEvent evt)

Invoked when a mouse button has been pressed on a component.
– mouseReleased(MouseEvent evt)

Invoked when a mouse button has been released on a component.
– mouseClicked(MouseEvent evt)

Invoked when the mouse button has been clicked (pressed and
released) on a component.
– mouseEntered(MouseEvent e)
Invoked when the mouse enters a component.
–
mouseExited(MouseEvent e)
Invoked when the mouse exits a component.
COMP201 Topic 9 / Slide 36
MouseEvent

MouseMotionListener

mouseMoved(MouseEvent evt)
– API: Invoked when the mouse cursor has been moved onto a
component but no buttons have been pushed.
– Actual: invoked frequently while mouse is moving

mouseDragged(MouseEvent evt)
– API: Invoked when a mouse button is pressed on a component and
then dragged.
– Actual: invoked frequently while mouse is being dragged
COMP201 Topic 9 / Slide 37
MouseEvent
MouseTest.java -- place, move, and erase squares
Setup:
class MousePanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
// draw all squares
for (int i = 0; i < squares.size(); i++)
g2.draw((Rectangle2D)squares.get(i));
}
private static final int SIDELENGTH = 10;
private ArrayList squares;
private Rectangle2D current;
…
}
COMP201 Topic 9 / Slide 38
MouseEvent
MousePanel –Basic methods
class MousePanel extends JPanel
{…
// Finds the first square containing a point.
// Returns null when no square contains the point
public Rectangle2D find(Point2D p){…}
// Adds a square to collection
public void add(Point2D p){…}
// Removes a square to collection
public void remove(Point2D p){…}
…
}
COMP201 Topic 9 / Slide 39
MouseEvent
MousePanel generates MouseEvents, which will be handled by
MouseHandler and MouseMotionHandler
class MousePanel extends JPanel
{
}
…
public MousePanel()
{ squares = new ArrayList();
current = null;
addMouseListener(new MouseHandler());
addMouseMotionListener(
new MouseMotionHandler());
} …
COMP201 Topic 9 / Slide 40
MouseEvent
MouseHandler is an inner class of MousePanel
class MousePanel extends Jpanel
{
private class MouseHandler implements MouseListener
{
public void mousePressed(MouseEvent event)
{
// add a new square if the cursor isn't inside a square
current = find(event.getPoint());
if (current == null)
add(event.getPoint()); }
public void mouseClicked(MouseEvent event)
{ // remove the current square if double clicked
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2)
remove(current);
…
COMP201 Topic 9 / Slide 41
A side note: Adapter classes
class MouseHandler implements MouseListener
{
public void mousePressed(MouseEvent event) { ..}
public void mouseClicked(MouseEvent event) {..}
}


not needed

mouseReleased(MouseEvent evt)


mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
But we have to implement it anyway
class MouseHandler implements MouseListener
{
public void mousePressed(MouseEvent event) { ..}
public void mouseClicked(MouseEvent event) {..}
public void mouse Released(MouseEvent event) {}
// does nothing. No code
Public void mouseEntered(MouseEvent e){}
Public void mouseExited(MouseEvent e){}
}
COMP201 Topic 9 / Slide 42
A side note: Adapter classes

Adaptor classes are introduced to save us from the trouble of providing
empty methods

Example:
– MouseAdapter is a class that consists of default implementation (do
nothing) of all the three methods in MouseListener
– Hence, the following is fine
class MouseHandler extends MouseAdapter
public void mousePressed(MouseEvent event) { ..}
public void mouseClicked(MouseEvent event) {..}
{
}



No compiler error even though mouseReleased, mouseEntered, and
mouseExited are not provided.
MouseHandler objects are MousListeners.
Most listener interfaces have adapter classes
COMP201 Topic 9 / Slide 43
MouseEvent
Using adapter class, we now have:
class MousePanel extends Jpanel
{
private class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
// add a new square if the cursor isn't inside a square
current = find(event.getPoint());
if (current == null)
add(event.getPoint()); }
public void mouseClicked(MouseEvent event)
{ // remove the current square if double clicked
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2)
remove(current);
…
COMP201 Topic 9 / Slide 44
MouseEvent
MouseMotionHandler is also an inner class of MousePanel
class MousePanel extends Jpanel
{
private class MouseMotionHandler
implements MouseMotionListener
{
public void mouseMoved(MouseEvent event){…}
public void mouseDragged(MouseEvent event)
{
if (current != null)
{
int x = event.getX(); int y = event.getY();
// drag the rectangle to center it at (x, y)
current.setFrame(x - SIDELENGTH/2,
y - SIDELENGTH/2, SIDELENGTH, SIDELENGTH);
repaint();
}
}
COMP201 Topic 9 / Slide 45
Objective and Outline

Objective:


Show how to write GUI programs that react to user actions.
Outline:

Java AWT event delegation model
– An example


The AWT event hierarchy
Individual events
– KeyEvents
– MouseEvents

Special classes and interfaces for event handling
– Adapter classes
– The Action interface
COMP201 Topic 9 / Slide 46
The Action Interface

Run ActionTest.java

One can change background color by doing one of the following:
1. Click on one of the buttons
2. Press a key :
ctrl B = blue, ctrl Y = Yellow, ctrl R = red
COMP201 Topic 9 / Slide 47
The Action Interface
How to write the program?
Do set up first
class ActionPanel extends JPanel
{
public ActionPanel()
{
// add buttons for these actions
add(new JButton(“Red”));
add(new JButton(“Blue”));
add(new JButton(“Yellow”));
}
public void actionPerformed(ActionEvent event)
{
setBackground(…);
repaint();
}
}
COMP201 Topic 9 / Slide 48
The Action Interface

How to handle events?

Need a class to listen for ActionEvent from button
Class Listener1 implements ActionListener
{ public void actionPerformed (ActionEvent e)
{ // action codes: change background colour
}
}

Also need a class to listen for KeyEvent from keystroke
Class Listener2 implements KeyListener
{ public void keyPressed (ActionEvent e)
{ // action codes: change background colour
}
}
Bad solution: “action codes” appear in two different places
COMP201 Topic 9 / Slide 49
The Action Interface

Better solution


Place “action codes” in one class, called action class
Associate objects of the action class to different event sources
– This mechanism is provided in Swing, beyond the AWT event model.
Event Source 1
Event Soure 2
Action Class Object
Action Codes
COMP201 Topic 9 / Slide 50
The Action Interface

Next


How to write action classes?
How to associate action objects with event sources?
COMP201 Topic 9 / Slide 51
The Action Interface

The interface Javax.swing.Action introduced for specifying actions
 Extends ActionListener
– Has method: place for placing action codes
void actionPerformed(ActionEvent evt)

Other methods for specifying features of the action:
– setEnabled(boolean b), boolean isEnabled()
– void putValue(String key, Object value)
– Object getValue(String key)
– (key value pairs can be used to store parameters necessary for
carrying out the action, i.e. colour)
– …
COMP201 Topic 9 / Slide 52
The Action Interface
• Class AbstractAction is a default implementation of Action
– The only abstract method is actionPerformed()
• Instead of implementing Action, you can simply extending
AbstractAction (similar to adapter class)
COMP201 Topic 9 / Slide 53
The Action Interface

Action class for our example:
.class ColorAction extends AbstractAction
{ public ColorAction(String name, Icon icon, Color c)
{ putValue(Action.NAME, name);
putValue(Action.SMALL_ICON, icon);
putValue("Color", c);
}
public void actionPerformed(ActionEvent evt)
{ Color c = (Color)getValue("Color");
setBackground(c);
repaint();
}
}
Action.NAME and Action.SMALL_ICON are used in display on buttons
COMP201 Topic 9 / Slide 54
The Action Interface

Make objects of the ColorAction Class
Action blueAction =
new ColorAction("Blue",
new ImageIcon("blue-ball.gif"),
Color.blue);
Action yellowAction =
new ColorAction("Yellow",
new ImageIcon("yellow-ball.gif"),
Color.yellow);
Action redAction =
new ColorAction("Red",
new ImageIcon("red-ball.gif"),
Color.red);
COMP201 Topic 9 / Slide 55
The Action Interface

Next


How to write action classes?
How to associate action objects with event sources?
COMP201 Topic 9 / Slide 56
The Action Interface

How do we associate the action objects with event sources?

The answer is easy for one event source: buttons
– Associate those actions with buttons by invoke JButton constructor
which takes an Action object
– Add those buttons to this JPanel
Class ActionPanel extends JPanel
{
add(new JButton(yellowAction));
add(new JButton(blueAction));
add(new JButton(redAction));
…
}
COMP201 Topic 9 / Slide 57
The Action Interface

How do we associate the action objects with keystrokes?

InputMap provides a binding between an input event (currently only
KeyStrokes are used) and an Object

ActionMap provides mappings from Objects to Actions

So, we have this solution
InputMap imap = new InputMap();
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
ActionMap amap = new ActionMap();
amap.put("panel.yellow", yellowAction);
COMP201 Topic 9 / Slide 58
The Action Interface

The solution on the previous slide does not work

We did not specify where the maps should take effect
– We want them to take effect within ActionPanel and nowhere else.

How to create maps what take effect within ActionPanel?
COMP201 Topic 9 / Slide 59
The Action Interface

JComponent has method
public final InputMap getInputMap(int condition)
that returns the map used under each of the following conditions
1. JComponent.WHEN_FOCUSED
When this component has keyboard focus
2. JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
When this component contains the component that has keyboard focus
3. JComponent.WHEN_IN_FOCUSED_WINDOW
When this component is contained in the same window as the component
that has keyboard focus
COMP201 Topic 9 / Slide 60
The Action Interface

JComponent has method
public final ActionMap getActionMap()
that returns the ActionMap used to determine what Action
to fire for particular KeyStroke binding
COMP201 Topic 9 / Slide 61
The Action Interface

The correct solution:
Class ActionPanel extends JPanel
{
InputMap imap = getInputMap( // since 1.3
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
ActionMap amap = getActionMap();
amap.put("panel.yellow", yellowAction);
…..
}
COMP201 Topic 9 / Slide 62
The Action Interface
Summary: To make action objects for multiple event sources
1.
Make a class that extends the AbstractAction.
2.
Make an object of that class.
3.
Construct a button or menu item with that object.
l
The constructor will read the label text and icon from the action object.
COMP201 Topic 9 / Slide 63
The Action Interface
4. For action that can be triggered by keystrokes
1. Locate an appropriate component , such as a panel, within
which you want the keystrokes to invoke actions.
2.
Get the when_ancestor_of_focused_component input
map of the component.
 Make a KeyStroke object for the desired keystroke.
 Make an action key object, such as a string that describes
your action.
 Add the pair(keystroke, action key ) into the input map.
3.
Get the action map of the component. Add the pair (action key,
action object) into the map.