|
Chapter 12
Events
·
Java 1.0’s original outward rippling event model had shortcomings.
-
An event could only be handled by the component that originated the event
or one of its containers.
-
No way to disable processing of irrelevant events.
·
Java 1.1 introduced new “event delegation model”.
-
A component may be told which objects should be notified when the
component generates a particular kind of event.
-
If a component is not interested in an event type, those events won’t be
propagated.
·
Both models are supported in Java 2, but the old model will eventually
disappear. Both models should not be mixed in a single program. If we do that,
the program is most likely to fail.
·
Event delegation model’s main concepts: Event classes, Event listeners,
Explicit event enabling and Event adapter classes.
Event
Classes
·
Events are Java objects. All the pertinent information is encapsulated in
that object. The super class of all events is java.util.EventObject.
·
This java.util.EventObject class
defines a method that returns the object that generated the event:
Object
getSource()
·
All events related to AWT are in java.awt.event
package. AWTEvent is the abstract super class of all AWT events. This class
defines a method that returns the ID of the event. All events define constants
to represent the type of event.
int
getID() – returns an int in the form of an integer value that identifies the
type of event.
·
It is useful to divide the event classes into Semantic events and
Low-level events.
·
Semantic Events –
These
classes are used for high-level semantic events, to represent user interaction
with GUI. ActionEvent, AdjustmentEvent,
ItemEvent, TextEvent
|
Event
Class
|
Source
|
Event Types
|
|
ActionEvent
|
Button – when clicked
List – when doubleclicked
MenuItem – when clicked
TextField – when Enter key is pressed
|
ACTION_PERFORMED
|
|
AdjustmentEvent
|
Scrollbar – when adjustments are made
|
ADJUSTMENT_VALUE_CHANGED
|
|
ItemEvent
|
CheckBox – when selected or deselected
CheckboxMenuItem – same as checkbox
Choice – when an item is selected or deselected
List - when an item is selected or deselected
|
ITEM_STATE_CHANGED
|
|
TextEvent
|
TextField
TextArea
|
TEXT_VALUE_CHANGED
|
Methods defined in the events to get the information
about them.
|
Event
Class
|
Method
|
Description
|
|
ActionEvent
|
String getActionCommand
|
Returns the command name associated with this action
|
|
int getModifiers
|
Returns the sum of modifier constants corresponding to
the keyboard modifiers held down during this action.
SHIFT_MASK, ALT_MASK, CTRL_MASK, META_MASK
|
|
AdjustmentEvent
|
int getvalue
|
Returns the current value designated by the adjustable
component
|
|
ItemEvent
|
Object getItem
|
Returns the object that was selected or deselected
Label of the checkbox
|
|
int getStateChange
SELECTED DESELECTED
|
Returned value indicates whether it was a selection or
a de-selection that took place, given by the two constants in ItemEvent.
|
·
Low-level Events –
These
classes are used to represent low-level input or window operations. Several
low-level events can constitute a single semantic event.
ComponentEvent, ContainerEvent, FocusEvent, KeyEvent,
MouseEvent, PaintEvent, WindowEvent
|
Event
Class
|
Source
|
Event Types
|
|
ComponentEvent
|
All components
|
COMPONENT_SHOWN,
COMPONENT_HIDDEN, COMPONENT_MOVED, COMPONENT_RESIZED
AWT
handles this event automatically. Programs should not handle this event.
|
|
ContainerEvent
|
All containers
|
COMPONENT_ADDED,
COMPONENT_REMOVED
AWT
handles this event automatically. Programs should not handle this event.
|
|
FocusEvent
|
All components
|
FOCUS_GAINED,
FOCUS_LOST
Receiving
focus means the component will receive all the keystrokes.
|
|
InputEvent
|
All components
|
This
is an abstract class. Parent of KeyEvent and MouseEvent. Constants
for key and mouse masks are defined in this class.
|
|
KeyEvent
|
All components
|
KEYPRESSED,
KEYRELEASED, KEYTYPED (when a character is typed)
|
|
MouseEvent
|
All components
|
MOUSE_PRESSED,
MOUSE_RELEASED, MOUSE_CLICKED, MOUSE_DRAGGED, MOUSE_MOVED, MOUSE_ENTERED,
MOUSE_EXITED
|
|
PaintEvent
|
All components
|
This
event occurs when a component should have its paint()/update() methods
invoked. AWT handles this event automatically. Programs should not
handle this event. This event is not supposed to be handled by the event
listener model. Components should override paint/update methods to get
rendered.
|
|
WindowEvent
|
All windows
|
This
event is generated when an important operation is performed on a window.
WINDOW_OPENED,
WINDOW_CLOSING, WINDOW_CLOSED, WINDOW_ICONIFIED, WINDOW_DEICONIFIED,
WINDOW_ACTIVATED, WINDOW_DEACTIVATED
|
Methods defined in the events to get the information
about them.
|
Event
Class
|
Method
|
Description
|
|
ComponentEvent
|
Component getComponent
|
Returns a reference to the same object as getSource,
but the returned reference is of type Component.
|
|
ContainerEvent
|
Container getContainer
|
Returns the container where this event originated.
|
|
Component getChild
|
Returns the child component that was added or
removed in this event
|
|
FocusEvent
|
boolean isTemporary
|
Determines whether the loss of focus is permanent or
temporary
|
|
InputEvent
|
long getWhen
|
Returns the time the event has taken place.
|
|
int getModifiers
|
Returns the modifiers flag for this event.
|
|
void consume
|
Consumes this event so that it will not be
processed in the default manner by the source that originated it.
|
|
KeyEvent
|
int getKeyCode
|
For KEY_PRESSED or KEY_RELEASED events, this method can
be used to get the integer key-code associated with the key. Key-codes
are defined as constants is KeyEvent class.
|
|
char getKeyChar
|
For KEY_TYPED events, this method returns the Unicode
character that was generated by the keystroke.
|
|
MouseEvent
|
int getX
|
Return the position of the mouse within the originated
component at the time the event took place
|
|
int getY
|
|
Point getPoint
|
|
int getClickCount
|
Returns the number of mouse clicks.
|
|
WindowEvent
|
Window getWindow
|
Returns a reference to the Window object that caused
the event to be generated.
|
Event
Listeners
·
Each listener interface extends java.util.EventListener
interface.
·
There are 11 listener interfaces corresponding to particular events. Any
class that wants to handle an event should implement the corresponding
interface. Listener interface methods are passed the event object that has all
the information about the event occurred.
·
Then the listener classes should be registered with the component that is
the source/originator of the event by calling the addXXXListener method on the
component. Listeners are unregistered by calling removeXXXListener method on the
component.
·
A component may have multiple listeners for any event type.
·
A component can be its own listener if it implements the necessary
interface. Or it can handle its events by implementing the processEvent method.
(This is discussed in explicit event enabling section)
·
All registered listeners with the component are notified (by invoking the
methods passing the event object). But the order of notification is not
guaranteed (even if the same component is registered as its own listener). Also
the notification is not guaranteed to occur on the same thread. Listeners should
take cautions not to corrupt the shared data. Access to any data shared between
the listeners should be synchronized.
·
Same listener object can implement multiple listener interfaces.
·
Event listeners are usually implemented as anonymous classes.
|
Event
Type
|
Event
Source
|
Listener
Registration and removal methods provided by the source
|
Event
Listener Interface implemented by a listener
|
|
ActionEvent
|
Button
List
MenuItem
TextField
|
addActionListener
removeActionListner
|
ActionListener
|
|
AdjustmentEvent
|
Scrollbar
|
addAdjustmentListener
removeAdjustmentListner
|
AdjustmentListener
|
|
ItemEvent
|
Choice
List
Checkbox
CheckboxMenuItem
|
addItemListener
removeItemListner
|
ItemListener
|
|
TextEvent
|
TextField
TextArea
|
addTextListener
removeTextListner
|
TextListener
|
|
ComponentEvent
|
Component
|
add ComponentListener
remove ComponentListner
|
ComponentListener
|
|
ContainerEvent
|
Container
|
addContainerListener
removeContainerListner
|
ContainerListener
|
|
FocusEvent
|
Component
|
addFocusListener
removeFocusListner
|
FocusListener
|
|
KeyEvent
|
Component
|
addKeyListener
removeKeyListner
|
KeyListener
|
|
MouseEvent
|
Component
|
addMouseListener
removeMouseListner
|
MouseListener
|
|
addMouseMotionListener
removeMouseMotionListner
|
MouseMotionListener
|
|
WindowEvent
|
Window
|
addWindowListener
removeWindowListner
|
WindowListener
|
Event Listener interfaces and their methods:
|
Event
Listener Interface
|
Event
Listener Methods
|
|
ActionListener
|
void actionPerformed(ActionEvent evt)
|
|
AdjustmentListener
|
void adjustmentValueChanged(AdjustmentEvent evt)
|
|
ItemListener
|
void itemStateChanged(ItemEvent
evt)
|
|
TextListener
|
void textValueChanged(TextEvent
evt)
|
|
ComponentListener
|
void componentHidden(ComponentEvent
evt)
void componentShown(ComponentEvent
evt)
void componentMoved(ComponentEvent
evt)
void componentResized(ComponentEvent
evt)
|
|
ContainerListener
|
void componentAdded(ContainerEvent
evt)
void componentRemoved(ContainerEvent
evt)
|
|
FocusListener
|
void focusGained(FocusEvent
evt)
void focusLost(FocusEvent
evt)
|
|
KeyListener
|
void keyPressed(KeyEvent
evt)
void keyReleased(KeyEvent
evt)
void keyTyped(KeyEvent
evt)
|
|
MouseListener
|
void mouseClicked(MouseEvent
evt)
void mouseReleased(MouseEvent
evt)
void mousePressed(MouseEvent
evt)
void mouseEntered(MouseEvent
evt)
void mouseExited(MouseEvent
evt)
|
|
MouseMotionListener
|
void mouseDragged(MouseEvent
evt)
void mouseMoved(MouseEvent
evt)
|
|
WindowListener
|
void windowActivated(WindowEvent
evt)
void windowDeactivated(WindowEvent
evt)
void windowIconified(WindowEvent
evt)
void windowDeiconified(WindowEvent
evt)
void windowClosing(WindowEvent
evt)
void windowClosed(WindowEvent
evt)
void windowOpened(WindowEvent
evt)
|
Event
Adapters
·
Event Adapters are convenient classes implementing the event listener
interfaces. They provide empty bodies for the listener interface methods, so we
can implement only the methods of interest without providing empty
implementation. They are useful when implementing low-level event listeners.
·
There are 7 event adapter classes, one each for one low-level event
listener interface.
·
Obviously, in semantic event listener interfaces, there is only one
method, so there is no need for event adapters.
·
Event adapters are usually implemented as anonymous classes.
Explicit
Event Enabling
How events are produced and handled?
·
OS dispatches events to JVM. How much low-level processing is done by OS
or JVM depends on the type of the component. In case of Swing components JVM
handles the low-level events.
·
JVM creates event objects and passes them to the components.
·
If the event is enabled for that component, processEvent method in that
component (inherited from java.awt.Component) is called. Default behavior of
this method is to delegate the processing to more specific processXXXEvent
method. Then this processXXXEvent method invokes appropriate methods in all
registered listeners of this event.
·
All the registered listeners of the event for the component are notified.
But the order is not guaranteed.
·
This delegation model works well for pre-defined components. If the
component is customized by sub-classing another component, then it has the
opportunity to handle its own events by implementing appropriate processXXXEvent
methods or the processEvent method itself.
·
To handle its own events, the subclass component must explicitly enable
all events of interest. This is done by calling enableEvents method with
appropriate event masks in the constructor. Enabling more than one event
requires OR’ing corresponding event masks. These event masks are defined as
constants in java.awt.AWTEvent.
·
If the component wants to also notify the registered listeners for the
event, then the overriding methods should call the parent version of the methods
explicitly.
·
Component class has a method processMouseMotionEvent, even though there is
no event called MouseMotionEvent.
Steps
for handling events using listeners or by the same component
Delegating to listeners
|
Handling own events (explicit enabling)
|
|
1.
Create a listener class, either by implementing an event listener
interface or extending an event adapter class.
2.
Create an instance of the component
3.
Create an instance of the listener class
4.
Call addXXXListener on the component passing the listener object.
(This step automatically enables the processing of this type of event.
Default behavior of processEvent method in the component is to delegate
the processing to processXXXEvent and that method will invoke
appropriate listener class methods.)
|
1.
Create a subclass of a component
2.
Call enableEvents(XXX_EVENT_MASK) in the constructor.
3.
Provide processXXXEvent and/or processEvent in the subclass
component. If also want to notify the listeners, call parent method.
4.
Create an instance of the subclass component
|
|