Before we delve any further into Swing GUI programming, we need to learn about events.

What are Events?

Every GUI platform, be it Microsoft Windows, Motif on Unix, or the Macintosh GUI, employs the concept of events.  Different GUI platforms may use different terminology (for example, Microsoft Windows uses the term “Windows messages”), but they all use essentially the same concept.

Events can be things like:

  • Mouse clicks and movement
  • Keyboard key presses
  • Window [de]activation, [de]iconification, etc.
  • System-specific events
  • Any number of user-defined event types

Events are delivered using messages.   The operating system usually has a message system which can send and receive messages containing event information.

When you (or the system) sends a message, you send it to an object on the system — a window, a control (button, edit box, list control, whatever), etc.

Microsoft Windows, Mac, UNIX systems, etc. all use event-driven message sending mechanisms heavily in their windowing support.

Note, however, that while events are very important in GUI programming, there are also many other applications where events are useful.

Why are Events Important?

Event and message delivery are a major part of how windowing systems work, and therefore the messaging system must be efficient.

Objects in a windowing system typically sit around waiting to be told what to do — if they are told to do nothing, they’ll do exactly that!

Therefore, you need to understand how the events and messaging system work to make things work properly, and to make things work efficiently.

What are Event-Driven Systems?

Anything that typically sits around waiting to be told what to do, and responding to external stimuli, is event-driven.

An example of an environment which makes the event-driven nature of the system very obvious is Microsoft Visual Basic. Lots of programs have been modeled after VB, including many of the Java IDEs.

The Event Queue

Typically, each GUI implementation has a single first-in, first-out queue into which each generated event is placed.  Events are handled serially, to avoid timing conflicts among multiple events.

In the Java GUI, there is a special thread, called the Event Queue [Dispatch] Thread.  Events are queued to this thread, which processes them in the order in which they were added to the queue.

The Java Event Model

Here’s a quick summary and overview of the Java event model.

Soon, we’ll show lots of specific examples, so you can see how the model is used.

History

Originally, in JDK 1.0, Java shipped with a simple AWT for portable GUI programming.  It used a model for events based on class inheritance:

  • In order for a program to catch and process GUI events, it must subclass GUI components and override either action() or handleEvent() methods.
  • Returning true from one of these methods consumes the event so it is not processed further.
  • Otherwise the event is propagated sequentially up the GUI hierarchy until:
    • it is consumed, or
    • the root of the hierarchy is reached.

This means that programs have two choices for structuring their event handling code:

  • Each individual component can be subclassed to specifically handle its target events; the result is a plethora of classes.

or:

  • All events for an entire hierarchy (or subset) can be handled by a particular container; the result is that the container’s overridden action() or handleEvent() method must contain a complex conditional statement in order to process the events.

Note: If you ever find yourself writing action() or handleEvent() methods in your Java GUI programs, STOP!  You’re using the old (prehistoric!) event model.  Instead, learn and use the newer, much superior, event model.

Why a New Event Model?

The Java 1.0 event model was simple and well suited for writing basic applets and applications.

However, it did not scale well for larger Java programs because:

  • The requirement to subclass a component in order to make use of its functionality is cumbersome to developers, and improper use of subclassing.
  • The inheritance model does not lend itself well to maintaining a clean separation between the application model and the GUI, because application code must be integrated directly into the subclassed components at some level.
  • Since all event types are filtered through the same methods, the logic to process the different event types is complex and error-prone. This becomes worse as new event types are added to the AWT.
  • There is no filtering of events — they are always delivered to components whether those components actually handle them or not. This produces a general performance problem, particularly with high-frequency type events such as mouse moves.
  • For many components, the action() method passes a String parameter which is equivalent to either the label of the component (Button, MenuItem), or the item selected (List, Choice). This often results in poor coding and unwieldy string comparison logic that doesn’t localize (internationalize) well.

Relationship Between Models

The Java 1.0 event model is present, but deprecated in Java 1.1 and beyond.  

The two models can coexist.  However, it is very strongly emphasized that you should use only the JDK 1.1+ event model.In extremely rare cases, you may need to use the 1.0 event model for applets that you want to run in old Web browsers that were based on JDK 1.0.

However, now, all current browsers support recent versions of the JDK (at least JDK 1.3 or later), via the Java Plug-in.  The Java Plug-in comes with all recent versions of the JDK, and is installed when you install the JDK.

Note that applets have become passé in recent years.

The Java 1.1 Event Model

The Java 1.1 event model is a Delegation Event Model

It is used by both the GUI and by Java Beans (and virtually everything else that is coming out in the Java world!)

Events are no longer represented by a single event class (like java.awt.Event) with numeric ids.

Instead, events are represented by a hiearchy of event classes:

  • ActionEventWindowEventMouseEventKeyEvent, etc.

Since a single event class may be used to represent more than one event type (e.g. MouseEvent represents mouse up, mouse down, mouse drag, mouse move, etc.), some event classes may also contain an id (unique within that class) which maps it to its specific event types.

Every event is a subclass of java.util.EventObject

GUI Events are subclasses of java.awt.AWTEvent (which itself is a subclass of EventObject)

If a class is interested in an event, it declares itself to be a listener for that particular class of event.

When an Event Occurs

  • When a object that generates an event needs to tell a listener object that an event happened, the system:
    • Calls the appropriate method of the listener interface
    • Passes to that method an object of the appropriate type the extends from EventObject

AWT Event Hierarchy

The AWT Event classes and related interfaces form an inheritance hierarchy. Below is the inheritance hiearchy for Java 1.5.0.

Note that there are a few event classes and their associated listener interfaces that we will not be talking about;  we will concentrate on the most commonly used events.

Class Hierarchy

Interface Hierarchy

The Post-Java 1.1 Event Classes & Interfaces

The events available in the Java 1.1+ model may be classified into a set of event classes.

Associated with each event class is a corresponding listener interface, containing a set of listener methods, and, for those listeners which have more than a single method, an associated adapter class.

Event ClassTypeListener InterfaceListener MethodsAdapter Class
ActionEventSemanticActionListeneractionPerformed() 
AdjustmentEventSemanticAdjustmentListeneradjustmentValueChanged() 
ComponentEventLow-levelComponentListenercomponentHidden()
componentMoved()
componentResized()
componentShown()
ComponentAdapter
ContainerEventLow-levelContainerListenercomponentAdded()
componentRemoved()
ContainerAdapter
FocusEventLow-levelFocusListenerfocusGained()
focusLost()
FocusAdapter
ItemEventSemanticItemListeneritemStateChanged() 
KeyEventLow-levelKeyListenerkeyPressed()
keyReleased()
keyTyped()
KeyAdapter
MouseEventLow-levelMouseListenermouseClicked()
mouseEntered()
mouseExited()
mousePressed()
mouseReleased()
MouseAdapter
Low-levelMouseMotionListenermouseDragged()
mouseMoved()
MouseMotionAdapter
MouseWheelEventLow-LevelMouseWheelListenermouseWheelMoved() 
TextEventSemanticTextListenertextValueChanged() 
WindowEventLow-levelWindowListenerwindowActivated()
windowClosed()
windowClosing()
windowDeactivated()
windowDeiconified()
windowIconified()
windowOpened()
WindowAdapter
WindowFocusListenerwindowGainedFocus()
windowLostFocus()
WindowStateListenerwindowStateChanged()

Note that all low-level events extend from ComponentEvent.  All other events are classified as semantic events.

Swing Classes & Events

JFC(Java Foundation Classes)/Swing contains a very large number of classes, and so coming up with a table of events used by each Swing component is difficult, and would become obsolete very quickly.  

Note that many of the JFC/Swing classes, such as JFrameJPanel, etc., are subclasses of AWT component and other Swing component classes, and so inherit some of their event generation behavior.

To determine what events are generated by a JFC/Swing class, first look at the javadoc for that class:

  • Read the description of the class;  often there is a description of (some of) the events that the class generates, and under what circumstances.  Note that you may find that it’s buried somewhat, so read it thoroughly!
  • Look for methods in the class with the signature:
    public void addMumbleListener(MumbleEvent e)
    The presence of such a method indicates that the class generates events that can be listened for. ; The Mumble represents the type of event.
  • Now look at each superclass, following the same process, until you reach the top of the inheritance hierarchy.