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

发表评论

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

WordPress.com 徽标

您正在使用您的 WordPress.com 账号评论。 登出 /  更改 )

Google photo

您正在使用您的 Google 账号评论。 登出 /  更改 )

Twitter picture

您正在使用您的 Twitter 账号评论。 登出 /  更改 )

Facebook photo

您正在使用您的 Facebook 账号评论。 登出 /  更改 )

Connecting to %s