<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