Event and Listeners Lecture

http://download-llnw.oracle.com/javase/tutorial/uiswing/events/index.html

 

Events

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.

Java Class Hierarchy of Events

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.

 

Event Handling: Listeners

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.

 

Examples Event Listeners and Methods

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.

 

Event source with multiple listeners

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

 


MouseEvent and MouseListeners

http://download-llnw.oracle.com/javase/tutorial/uiswing/events/mouselistener.html

 

The MouseListener Interface

Method

Purpose

mouseClicked(MouseEvent)

Called just after the user clicks the listened-to component.

mouseEntered(MouseEvent)

Called just after the cursor enters the bounds of the listened-to component.

mouseExited(MouseEvent)

Called just after the cursor exits the bounds of the listened-to component.

mousePressed(MouseEvent)

Called just after the user presses a mouse button while the cursor is over the listened-to component.

mouseReleased(MouseEvent)

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.

The MouseEvent Class

Method

Purpose

int getClickCount()

Returns the number of quick, consecutive clicks the user has made (including this event). For example, returns 2 for a double click.

int getX()
int getY()
Point getPoint()

Return the (x,y) position at which the event occurred, relative to the component that fired the event.

int getXOnScreen()
int getYOnScreen()
int getLocationOnScreen()

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.

int getButton()

Returns which mouse button, if any, has a changed state. One of the following constants is returned: NOBUTTON, BUTTON1, BUTTON2, or BUTTON3. Introduced in release 1.4.

boolean isPopupTrigger()

Returns true if the mouse event should cause a popup menu to appear. Because popup triggers are platform dependent, if your program uses popup menus, you should call isPopupTrigger for all mouse-pressed and mouse-released events fired by components over which the popup can appear. See Bringing Up a Popup Menu for more information about popup menus.

String getMouseModifiersText(int)

Returns a String describing the modifier keys and mouse buttons that were active during the event, such as "Shift", or "Ctrl+Shift". These strings can be localized using the awt.properties file. Introduced in release 1.4.


The InputEvent Class

The MouseEvent class inherits many useful methods from InputEvent and a couple handy methods from the ComponentEvent and AWTEvent classes.

Method

Purpose

int getID()
(in java.awt.AWTEvent)

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: MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, and MouseEvent.MOUSE_CLICKED.

 

Component getComponent()
(in ComponentEvent)

Returns the component that fired the event. You can use this method instead of the getSource method.

 

int getWhen()

Returns the timestamp of when this event occurred. The higher the timestamp, the more recently the event occurred.

 

boolean isAltDown()
boolean isControlDown()
boolean isMetaDown()
boolean isShiftDown()

Return the state of individual modifier keys at the time the event was fired.

 

int getModifiers()

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.

 

int getModifiersEx()

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, META, just after the event occurred.

 

int getModifiersExText(int)

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

The MouseInfo class provides methods to obtain information about the mouse pointer location at any time while an application runs.

Method

Purpose

getPointerInfo()

Returns a PointerInfo instance that represents the current location of the mouse pointer.

getNumberOfButtons()

Returns the number of buttons on the mouse or -1 , if a system does not support a mouse.

 

 

Also look at MouseMotionListener and MouseWheelListener


KeyEvent and KeyListener

 

The KeyListener Interface

The corresponding adapter class is KeyAdapter.

Method

Purpose

keyTyped(KeyEvent)

Called just after the user types a Unicode character into the listened-to component.

keyPressed(KeyEvent)

Called just after the user presses a key while the listened-to component has the focus.

keyReleased(KeyEvent)

Called just after the user releases a key while the listened-to component has the focus.


The KeyEvent Class

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

int getKeyChar()

Obtains the Unicode character associated with this event. Only rely on this value for key-typed events.

int getKeyCode()

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 KeyEvent class defines many key code constants for commonly seen keys. For example, VK_A specifies the key labeled A, and VK_ESCAPE specifies the Escape key.

String getKeyText(int)
String getKeyModifiersText(int)

Return text descriptions of the event's key code and modifier keys, respectively.

int getModifiersEx()
String getModifiersExText(int modifiers)

Return the extended modifiers mask for this event. There are methods inherited from the InputEvent class. Extended modifiers represent the state of all modal keys. The getModifiersExText method returns a string describing the extended modifier keys and mouse buttons. Since the getModifiersEx and getModifiersExText methods provide more information about key events, they are preferred over the getKeyText or getKeyModifiersText methods.

boolean isActionKey()

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.

int getKeyLocation()

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 KEY_LOCATION_STANDARD, KEY_LOCATION_LEFT, KEY_LOCATION_RIGHT, KEY_LOCATION_NUMPAD, or KEY_LOCATION_UNKNOWN. This method always returns KEY_LOCATION_UNKNOWN for key-typed events. Introduced in JDK release 1.4.

 

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.

Timer Class

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.

Examples:

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.