Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / November 2006

Tip: Looking for answers? Try searching our database.

Bogus behavior of window listeners

Thread view: 
Twisted - 20 Nov 2006 04:08 GMT
I may have discovered another bug in the 1.6.0 release candidate
library implementation.

I mentioned earlier that my app's "are you sure?" on-exit dialog was
suddenly popping up twice. I've since found it popping up only once, as
it should, under a well-defined set of circumstances that prove the
culprit to be one of two occurrences of:

if (frame.getWindowListeners().length > 0)
    frame.removeWindowListener(frame.getWindowListeners()[0]);

This used to work -- the window always has exactly the one window
listener if it has any, and it's sometimes removed and replaced with a
different one, and all of this activity is restricted to the event
dispatch thread so there are no concurrency issues.

Now we have a clear case of where this fails exactly once. The app adds
an initial window listener, and at a later time when there's some
cleanup to be done on exit it replaces that one with a different one.
If the cleanup stops being needed, it replaces it again. Although the
code in that replace is identical to the code in the first, I expect
javac is probably dumb enough to create two different anonymous inner
classes for these, so the third and the first aren't the same class as
the JVM sees it.

So listener 1 is added, then removed and 2 added, then 2 removed and 3
added, 3 removed and 2 added, 2 removed and 3 added, and so forth. Or
so it used to go. Now, one of them (perhaps listener 1) lingers
forever.

Either adding the first window listener doesn't cause
frame.getWindowListeners().length > 0, or
frame.removeWindowListener(frame.getWindowListeners()[0]) simply
doesn't work properly. I'm guessing the former -- add listener 1 and
the array remains empty; add listener 2 and it grows an element; remove
it and add listener 3 works as it should; remove that and put 2 back
works as it should; and so forth.

Anyone else encountering this?
Andrew Thompson - 20 Nov 2006 06:10 GMT
> I may have discovered another bug in the 1.6.0 release candidate
> library implementation.

Bug ID?

(snip stuff about listeners and exit dialogs)

> Anyone else encountering this?

Code?

(And why are you posting a very GUI related question
on c.l.j.programmer, rather than c.l.j.gui?)

Andrew T.
Twisted - 20 Nov 2006 06:42 GMT
> > I may have discovered another bug in the 1.6.0 release candidate
> > library implementation.
>
> Bug ID?

?

> (snip stuff about listeners and exit dialogs)
>
> > Anyone else encountering this?
>
> Code?

?

> (And why are you posting a very GUI related question
> on c.l.j.programmer, rather than c.l.j.gui?)

Because this is the c.l.j group I have bookmarked?
Thomas Hawtin - 20 Nov 2006 13:41 GMT
> I mentioned earlier that my app's "are you sure?" on-exit dialog was
> suddenly popping up twice. I've since found it popping up only once, as
[quoted text clipped - 3 lines]
> if (frame.getWindowListeners().length > 0)
>     frame.removeWindowListener(frame.getWindowListeners()[0]);

You are assuming your listener is the only listener. That's not a good
assumption to make.

> Now we have a clear case of where this fails exactly once. The app adds
> an initial window listener, and at a later time when there's some
[quoted text clipped - 4 lines]
> classes for these, so the third and the first aren't the same class as
> the JVM sees it.

Why not use a debugger or printf?

Tom Hawtin
Twisted - 20 Nov 2006 22:55 GMT
> > I mentioned earlier that my app's "are you sure?" on-exit dialog was
> > suddenly popping up twice. I've since found it popping up only once, as
[quoted text clipped - 6 lines]
> You are assuming your listener is the only listener. That's not a good
> assumption to make.

In a part of the original posting that you conveniently snipped, I
explicitly stated that it is the only listener. I create the frame and
add just one. Later, under certain circumstances, code may remove it
and add a different one; again after that point there is only one.
There may be subsequent changes of the listener according to the same
pattern.

> Why not use a debugger or printf?

Printf? In Java? :)

Well, actually I may take some further steps to investigate this. I
thought of putting a number in the title bar of the dialog box to
identify which listener is responsible for it. Then I'll know exactly
which one isn't being removed.
Patricia Shanahan - 20 Nov 2006 23:35 GMT
...
>> Why not use a debugger or printf?
>
> Printf? In Java? :)

"printf" is a method in java.io.PrintStream, the class for both
System.err and System.out. It was added in 1.5.

> Well, actually I may take some further steps to investigate this. I
> thought of putting a number in the title bar of the dialog box to
> identify which listener is responsible for it. Then I'll know exactly
> which one isn't being removed.

Are you sure? Which one will your code display if you think you have
removed listener X, and have added listener Y?

I would be more direct about it, and put in a test for an existing
listener when one is about to be added.

Patricia
Thomas Hawtin - 20 Nov 2006 23:37 GMT
> In a part of the original posting that you conveniently snipped, I
> explicitly stated that it is the only listener. I create the frame and

It's the only listener you add. It's not necessarily the only listener.
PL&F add listeners. Components add listeners to models. Lots of
listeners are about that you never knew about.

> Printf? In Java? :)

Yeah, it's been in Java since 1.5 (I still use println myself).

Tom Hawtin
Patricia Shanahan - 21 Nov 2006 01:46 GMT
>> In a part of the original posting that you conveniently snipped, I
>> explicitly stated that it is the only listener. I create the frame and
>
> It's the only listener you add. It's not necessarily the only listener.
> PL&F add listeners. Components add listeners to models. Lots of
> listeners are about that you never knew about.

However, presumably Twisted only cares about the explicitly created
listeners. Presumably, they will belong to user program classes,
including anonymous inner classes in the user program, not PL&F
implementation classes.

Patricia
Patricia Shanahan - 21 Nov 2006 02:02 GMT
>>> In a part of the original posting that you conveniently snipped, I
>>> explicitly stated that it is the only listener. I create the frame and
[quoted text clipped - 7 lines]
> including anonymous inner classes in the user program, not PL&F
> implementation classes.

I'm going to take that back. I just took another look at the base
message of this thread:

"if (frame.getWindowListeners().length > 0)
frame.removeWindowListener(frame.getWindowListeners()[0]);"

This code could be a really bad idea if there is ever a library
implementation listener attached to frame. Suppose the first element of
the array is a library listener, and the second is Twisted's. The
library listener gets removed, and Twisted's listener stays, as another
one is added.

I've never tried to remove an arbitrary listener, only ones I added, so
I have no practical experience of the effects of doing this.

Patricia
Twisted - 21 Nov 2006 14:24 GMT
> It's the only listener you add. It's not necessarily the only listener.
> PL&F add listeners. Components add listeners to models. Lots of
> listeners are about that you never knew about.

It worked before, so it seems doubtful that this could be the
explanation.
Patricia Shanahan - 21 Nov 2006 15:13 GMT
>> It's the only listener you add. It's not necessarily the only listener.
>> PL&F add listeners. Components add listeners to models. Lots of
>> listeners are about that you never knew about.
>
> It worked before, so it seems doubtful that this could be the
> explanation.

The explanation that Thomas' observation suggests would lead to bugs
where any change in your program or the graphics libraries, even
apparently harmless changes, could matter.

You remove, in effect, an arbitrary Window listener, and then assume
that your listener has been removed.

The API documentation makes no statements about the order of listeners
in the array returned by getWindowListener, so the order could change,
for exactly the same combination of add and remove operations, from
release to release of the software. If your listener happens to be
referenced by element 0, all will be well. If not, you would get exactly
the symptoms you describe, plus possibly additional symptoms. There may
be consequences to the library failing to react to the condition the
removed listener was dealing with.

There is a really simple way to test for this issue. Change:

if (frame.getWindowListeners().length > 0)
    frame.removeWindowListener(frame.getWindowListeners()[0]);

to

WindowListener[] listeners = frame.getWindowListeners();
if (listeners.length > 0){
   if(listeners.length.length == 1){
    frame.removeWindowListener(listeners[0]);
   }else{
        *** write debug output or throw an exception
   }
}

Patricia


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.