Java Reference
In-Depth Information
■
Tip
Personally, I don't like the approach of just associating a class as the event listener, because it doesn't
scale well when the situation gets more complicated. For instance, as soon as you add another button onto
the screen and want the same event listener to handle its selection, the
actionPerformed()
method must
figure out which button triggered the event before it can respond. Although creating a separate event listener
for each component adds another class to the set of deliverables, creating separate listeners is more main-
tainable than sharing a listener across multiple components. In addition, most integrated development
environment (IDE) tools, such as Borland's JBuilder, can automatically create the listener objects as separate
classes.
Multithreaded Swing Event Handling
To increase their efficiency and decrease the complexity, all Swing components were designed
to
not
be thread-safe. Although this might sound scary, it simply means that all access to Swing
components needs to be done from a single thread—the event-dispatch thread. If you are
unsure that you're in a particular thread, you can ask the
EventQueue
class with its
public static
boolean isDispatchThread()
method or the
SwingUtilities
class with its
public static boolean
isEventDispatchThread()
method. The latter just acts as a proxy to the former.
■
Note
Earlier versions of this topic showed one particular way of creating Swing programs. They were
wrong. It was thought that accessing invisible (unrealized) components from outside the event-dispatch
thread was okay. However, that's not true. Doing something with a Swing component can trigger a reaction
within the component, and that other action would be done on the event-dispatch thread, violating the single-
threaded access.
With the help of the
EventQueue
class, you create
Runnable
objects to execute on the event-
dispatch thread to properly access components. If you need to execute a task on the event-dispatch
thread, but you don't need any results and don't care exactly when the task finishes, you can
use the
public static void invokeLater(Runnable runnable)
method of
EventQueue
. If, on the
other hand, you can't continue with what you're doing until the task completes and returns
a value, you can use the
public static void invokeAndWait(Runnable runnable)
method of
EventQueue
. The code to get the value is left up to
you
and is not the return value to the
invokeAndWait()
method.
■
Caution
The
invokeAndWait(Runnable)
method can throw an
InterruptedException
or an
InvocationTargetException
.