Another analysis of a vanilla swing event listener

See also http://bigblog.tanbin.com/2011/02/deeper-look-at-swing-event-handlers.html

Case study — http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

Be crystal clear about
* registration time — could happen hours before
* produce-time
* consume-time

How many threads?
– EDT is the consumer thread
– producer thread
– registration thread? less relevant. can be any thread.

Data shared among these threads at these different TIMES?
+ (singleton) jcomponent object
+ (singleton) action listener object
+ event-queue-task objects.

Before registration time, action listener is instantiated. At registration time, address of the listener object is saved in jcomponent object — like a subscriber mailing list (or spam list:)

At produce-time, system instantiates event-queue-task object (different from EventObject), injecting the jcomponent (as event source) + Listener object addresses therein, then enqueues the task object to the EDT event-queue. If 5 listeners registered, then 5 distinct task objects enqueued.

At consume-time (shortly but possibly much later [1]), EDT picks up the task object and finds the listener object, and calls listener.actionPerformed() passing in EventObjectt. As a non-static method, this CALL’s host object is the listener object but it executes on EDT. At consume-time, all instance fields of the source object (typically a jcomponent), instance fields of the listener (and, if a nested class within a jcomponent, private fields of the enclosing jcomponent) are accessible.

Listener OBJECT is often of an inner class –> Complicating. You need to be very clear that registration time and listener creation time are rather less relevant since they could be well before the event. Enclosing class’s fields all become accessible to actionPerformed().

If inner class is local, then local variables of the enclosing METHOD are also accessible, if FINAL. This last FINAL scenario is more tricky. The local vars are created at registration time but (because FINAL) remain accessible at consume-time.

[1] that’s why async always needs buffer — see http://bigblog.tanbin.com/2011/05/asynchronous-always-requires-buffer-and.html

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s