http://download-llnw.oracle.com/javase/tutorial/uiswing/events/index.html
Interactions with applications are implemented using events and listeners. The user (or some other application) does something that generates an event. A listener gets the events and responds to it.
EventObject
- base class for all
events
AWTEvent
- Window and interaction
events
ActionEvent
- indicates that a component-defined action
occurred.
AdjustmentEvent
- The adjustment event
emitted by Adjustable objects.
ItemEvent
- indicates that an item was selected or deselected.
TextEvent
- indicates that an object's text changed.
ComponentEvent
- A low-level event which indicates that a
component moved, changed size, or changed visibility (also, the root class for
the other component-level events).
ContainerEvent
- indicates that a container's contents
changed because a component was added or removed.
FocusEvent
- indicates that a Component has gained or lost the input focus.
PaintEvent
- The component-level paint event.
WindowEvent
- indicates that a window has changed its
status.
InputEvent
- The root event class for all component-level input events.
MouseEvent
KeyEvent
Events have sources which correspond to the Component that generated the event.
All windowing toolkits have events but they handle events differently. Java uses listeners, which is OO (class) version to event handler call back functions. Other toolkits use an event loop where the programmer has to maintain the event-loop.
There are different types of Listeners for different Events. Actually Java only gives you interfaces. You have to implement the methods so that the action you want occurs after an event.
ActionListener
actionPerformed
(
ActionEvent
)
ItemListener
itemStateChange
(
ItemEvent
)
WindowListener
windowClosing
(
WindowEvent
)
windowOpened
(
WindowEvent
)
windowIconified
(
WindowEvent
)
windowClosed
(
WindowEvent
)
windowOctivated
(
WindowEvent
)
windowDeactivated
(
WindowEvent
)
ComponentListener
componentMoved
(
ComponentEvent
)
componentHidden
(
ComponentEvent
)
componentResized
(
ComponentEvent
)
componentShown
(
ComponentEvent
)
KeyListner
keyPressed
(
KeyEvent
)
keyReleased
(
KeyEvent
)
MouseListener
mousePressed
(
MouseEvent
)
mouseReleased
(
MouseEvent
)
mouseEntered
(
MouseEvent
)
mouseClicked
(
MouseEvent
)
MouseMotionListener
mouseDragged
(
MouseEvent
)
mouseMoved
(
MouseEvent
)
Frequently in Java the Component containing the source implements the event. So you see:
public
class MyPanel extends JPanel implements TheListener{
...
thisHappend
(
ThisEvent
thisEvent){ // the Listener interface method
// interrogate thisEvent
// do something because of thisEvent
}
}
Note that paint methods are responding to PaintEvent.
Multiple listeners can register to be notified of events of a particular type from a particular source. Also, the same listener can listen to notifications from different objects.
Listeners have to be registered with Components that generate the event. The Component that will generate the event must have a line like:
public
class MyButton extends JButton {
MyButton
(
ActionListener
actionListener){
this.addActionListener(actionListener);
}
}
Note you will even have to do this if the Component handles it own events so in the example above
public
class MyPanel extends JPanel implements TheListener{
MyPanel
(
){
this.addTheListener(this);
}
thisHappend
(
ThisEvent
thisEvent){ // the Listener interface method
// interrogate thisEvent
// do something because of thisEvent
}
}
DO NOT FORGET TO REGISTER the listener; this is the NUMBER ONE ERROR using Listeners. It is a hard error to debug because there is no error message, the program just does not do what you want it to do.
Because the above looks a little funny, there are other techniques:
1. Use an inner class, simple enough but does not save typing, and cannot be reused.
2. Anonymous Class Listeners - I do not really approve because it is hard to read, but it is used frequently, so you should be able to identify it. The notion is that if the Listener is not going to be reused then you should not have to name it.
Example consider that your JPanel has buttons and
public
class MyPanel extends JPanel implements TheListener{
JButton
myButton = new JButton();
MyPanel
(
){
myButton.addActionListener(
new
ActionListener(){
public
void actionPerformed(ActionEvent e){
//
do something
}
// end actionPerformed
}
// end new ActionListener
)
// end addActionListener()
}
}
The only thing you need to know to react to mouse and key events is the event class
http://download-llnw.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
Method |
Purpose |
Called just after
the user clicks the listened-to component. |
|
Called just after
the cursor enters the bounds of the listened-to component. |
|
Called just after
the cursor exits the bounds of the listened-to component. |
|
Called just after
the user presses a mouse button while the cursor is over the listened-to
component. |
|
Called just after the
user releases a mouse button after a mouse press over the listened-to
component. |
The MouseAdapter class (the AWT adapter class) is
abstract. All its methods have an empty body. So a developer can define methods
for events specific to the application. You can also use the MouseInputAdapter class, which has all the
methods available from MouseListener and MouseMotionListener.
Method |
Purpose |
Returns the number of quick, consecutive clicks the user
has made (including this event). For example, returns 2 for a double click. |
|
Return the (x,y)
position at which the event occurred, relative to the component that fired the
event. |
|
int getXOnScreen() |
Return the absolute (x,y) position of the event. These coordinates are
relative to the virtual coordinate system for the multi-screen environment.
Otherwise, these coordinates are relative to the coordinate system associated
with the Component's Graphics Configuration. |
Returns which mouse button, if any, has a changed state.
One of the following constants is returned: |
|
Returns |
|
Returns a |
The MouseEvent
class inherits many useful methods from InputEvent and a couple handy
methods from the ComponentEvent
and AWTEvent
classes.
Method |
Purpose |
|
int getID() |
Returns the event type, which defines the particular
action. For example, the MouseEvent id reflects the
state of the mouse buttons for every mouse event. The following states could
be specified by the MouseEvent id: |
|
Component getComponent() |
Returns the component that fired the event. You can use this
method instead of the |
|
Returns the timestamp of when this event occurred. The
higher the timestamp, the more recently the event occurred. |
|
|
boolean isAltDown() |
Return the state of individual modifier keys at the time
the event was fired. |
|
Returns the state of all the modifier keys and mouse buttons when the event was fired. You can use this method to determine which mouse button was pressed (or released) when a mouse event was fired. |
|
|
Returns the extended modifier mask for this event.
Extended modifiers represent the state of the mouse button and all modal
keys, such as ALT, CTRL, |
|
|
Returns a string describing the extended modifier keys and
mouse buttons, such as "Shift", "Button1", or "Ctrl+Shift". These strings can be localized by
changing the awt.properties file. Introduced in
release 1.4. |
|
The MouseInfo
class provides methods to obtain information about
the mouse pointer location at any time while an application runs.
Method |
Purpose |
Returns a |
|
Returns the number of buttons on the mouse or |
Also look at MouseMotionListener and MouseWheelListener
The corresponding adapter class is KeyAdapter
.
Method |
Purpose |
Called just after the user types a Unicode character into
the listened-to component. |
|
Called just after the user presses a key while the
listened-to component has the focus. |
|
Called just after the user releases a key while the listened-to
component has the focus. |
The KeyEvent
class inherits many useful methods from the InputEvent
class, such as getModifiersEx
,
and a couple of useful methods from the ComponentEvent
and AWTEvent
classes. See the InputEvent Class table in the mouse
listener page for a complete list.
Method |
Purpose |
Obtains the Unicode character associated with this event.
Only rely on this value for key-typed events. |
|
Obtains the key code associated with this event. The key
code identifies the particular key on the keyboard that the user pressed or
released. The |
|
Return text descriptions of the event's key code and
modifier keys, respectively. |
|
int getModifiersEx()
|
Return the extended modifiers mask for this event. There
are methods inherited from the |
Returns true if the key firing the event is an action key.
Examples of action keys include Cut, Copy, Paste, Page Up, Caps Lock, the
arrow and function keys. This information is valid
only for key-pressed and key-released events. |
|
Returns the location of the key that fired this event.
This provides a way to distinguish keys that occur more than once on a
keyboard, such as the two shift keys, for example. The possible values are |
I have found that the JFrame always reliably hears. If you want a component (even the content pane) to hear its own key presses then having the JFrame implement KeyListener does not help. To insure that the component implementing KeyListener hears reliably add to component's constructor:
this.setFocusable
(
true);
See the Title class in the TalkingPendulum project. TalkingPendulum is a good first example.
Generally components are the sources of action events, but there is another source, Timer.
Timer is useful to delaying an action or to animate a sequence.
Generally you'll only need:
Timer(
int
delay, ActionListener actListener)
-
Create the timer with a delay and ActionEventListener
void
start() - starts the Timer
void
stop() - stops the Timer
addActionListener
(
ActionListener
)
setDelay
(
int
)
The Component generating the animation can have its own timer, but note that for Java Swing there is only one Timer thread. This is a good thing, so that the times are synchronized.
public
MovingImage extends JPanel implements ActionListener{
private
Image image;
Timer
timer;
int
delay = 1; // in ms
public
MovingImage(Image image, int delay){
this.image
= image;
timer
= new Timer(delay, this)
timer.start
(
) // do not forget
}
// end MovingImage()
public
void actionPerformed(ActionEvent e){
repaint(
);
}
// end actionPerformed()
protected
void paintComponent(Graphics
g){
time ++;
x
= (time%this.getWidth()); // does this work? for time
< this.getWidth();
y
= this.getHeight()/2;
g.drawImage
(
image, x, y, this);
}
// end paintComponent()
}
// end MovingImage class
The ActionListener can stop the timer and start it again using Timer.stop() and Timer.start(), but then it will need a reference to the Timer.
This is a good time to review MySwingingPanel. SwingPendulum is the ActionListener.
1. KeyListener - TalkingPendulum, note Title is KeyListener and setFocusable(true) in constructor is necessary.
2. Timer - MySwingingPanel, note SwingPendulum is ActionListener.
3. MouseListener - ShootSwingingPendulum, note ListeningBulb is the MouseListener.