<AWT Dev> Problem with modal Dialog

Artem Ananiev Artem.Ananiev at Sun.COM
Mon Feb 16 23:29:59 PST 2009


Oleg Sukhodolsky wrote:
> Hi Artem,
> 
> On Mon, Feb 16, 2009 at 7:15 PM, Artem Ananiev <Artem.Ananiev at sun.com> wrote:
>> Roman Kennke wrote:
>>> Hi Artem,
>>>
>>>>>>>> Hrmpf. Seems I cannot. The disclaimer says 'During the initial
>>>>>>>> rollout
>>>>>>>> phase, this site will only be accepting and tracking patch
>>>>>>>> contributions
>>>>>>>> from developers without push access to the OpenJDK 6 and 7 forests.'
>>>>>>>> and
>>>>>>>>  since I _have_ push access, I can't file bug reports. Too bad.
>>>>>>>>
>>>>>>>> BTW, simply sending this over the EQ is no solution either, because
>>>>>>>> then
>>>>>>>> later it will fail to invokeAndWait(). I will think a little more
>>>>>>>> about
>>>>>>>> this, or maybe anybody has a quick idea?
>>>>>>> Just an idea (have not evaluated it carefully):
>>>>>>> perhaps we should set keepBlockingEDT to false not in
>>>>>>> hideAndDisposeHandler(),
>>>>>>> but in WakingRunnable.run() instead.
>>>>>> I'm looking at this problem at the moment. The problem is the instance
>>>>>> of WakingRunnable is not run on EDT at all - I don't know why.
>>>>> I know why. It is because the DisposeAction is run _immediately_, before
>>>>> the WakingRunnable had a chance. This DisposeAction calls removeNotify(),
>>>>> which leads to all events on the EQ that are related to the Dialog beeing
>>>>> discarded.
>>>> Could you, please, point to the place where all the events are discarded?
>>>> I don't see any.
>>> In Component.removeNotify(), we call this:
>>>
>>> Toolkit.getEventQueue().removeSourceEvents(this, false);
>> OK, I see. What a wonderful code...
>>
>>> which removes all events related to the component. removeNotify() is
>>> called from inside the DisposeAction.
>> For this particular case it's enough to add some additional check to
>> hideAndDisposeHandler:
>>
>>         if (showAppContext != curAppContext) {
>>             // Wake up event dispatch thread on which the dialog was
>>             // initially shown
>>             SunToolkit.postEvent(showAppContext, wakingEvent);
>>             showAppContext = null;
>> +        } else if (EventQueue.isDispatchThread()) {
>> +            waking.run();
>>         } else {
>>             Toolkit.getEventQueue().postEvent(wakingEvent);
>>         }
> 
> this change will fix this particular test, but the same problem may
> exists even when
> we call hide() not on EDT, it is just a little bit harder to write
> test for this ;)

Well, you're right, it's possible to create such test (post 'dispose' to 
EDT and immediately call 'hide' on main), but it is even more artificial 
case :)

> What about moving resetting keepBlockingEDT to WakingEvent.run(), or,
> perhaps, we can simply change
> target of WakingEvent from a dialog to toolkit.
> What do you think?

I'd prefer if hideAndDisposeHandler() can wait for the waking runnable 
to execute on EDT, so the calling thread is unblocked immediately after 
the call to hide() or dispose(). Of course, the case when the dialog is 
shown on EDT should be covered separately.

Clearing keepBlockingEDT flag in WakingRunnable.run() would lead to 
several waking runnables to be posted to EDT (and only the last one to 
be really dispatched) which looks weird. Making toolkit be the source of 
the event also looks like a workaround, however it's definitely safe and 
short fix.

Thanks,

Artem

BTW, do you know why all the component's events are removed from 
EventQueue when it is being disposed?

> Oleg.
> 
>> Thanks,
>>
>> Artem
>>
>>> /Roman
>>>



More information about the awt-dev mailing list