API REVIEW request for RT-19783: Provide an option to allow modal windows to be blocking

Jeff McDonald deep.blue.6802 at gmail.com
Wed Apr 11 09:58:30 PDT 2012


I put together a truth table of sorts to help me visualize the possible
states. It's an ASCII chart so it needs to be viewed using a monspaced font
for everything to line up.


+--------------------------------+----------------------------------------+--------------------------------------------+
    | Modality.NONE                  | Modality.WINDOW
   | Modality.APPLICATION                       |
    | initModality(Modality.NONE)    | initModality(Modality.WINDOW_MODAL)
   | initModality(Modality.WINDOW_MODAL)        |
+-------------------+--------------------------------+----------------------------------------+--------------------------------------------+
| un-blocked        | Supported (This is typical)    | Supported
                   | Supported                                  |
| show()            | 1. initModality(Modality.NONE) | 1.
initModality(Modality.WINDOW_MODAL) | 1.
initModality(Modality.WINDOW_MODAL)     |
|                   | 2. show()                      | 2. show()
                   | 2. show()                                  |
|                   | or just                        |
                   |                                            |
|                   | 1. show()                      |
                   |                                            |
+-------------------+--------------------------------+----------------------------------------+--------------------------------------------+
| blocked           | Unsupported                    | Supported
                   | Supported                                  |
| showAndWait()     | Throws exception               | 1.
initModality(Modality.WINDOW_MODAL) | 1.
initModality(Modality.APPLICATION_MODAL)|
| (proposed)        |                                | 2. showAndWait()
                  | 2. showAndWait()                           |
+-------------------+--------------------------------+----------------------------------------+--------------------------------------------+

I propose the following changes:
1. show() remains the same as it is now.
2. add showWindowModal(boolean wait)
3. add showAppModal(boolean wait)
4. remove initModality()
5. Add Tom's description of "modal" and "blocking" to the JavaDocs. His
wording is clear and concise.

The justification: The API is clearer and easier to understand because only
one method call is required to execute the desired behavior instead of two
method calls. The second benefit is that a single method call eliminates
the potential of calling the initModality and show() / showAndWait()
methods in the incorrect order.

On Wed, Apr 11, 2012 at 5:06 AM, Kevin Rushforth <kevin.rushforth at oracle.com
> wrote:

> Thanks, Artem!
>
> Good suggestion, and I will add that to the description, since someone may
> be puzzled by the behavior if we don't.
>
> -- Kevin
>
>
>
> Artem Ananiev wrote:
>
>> Hi, Kevin,
>>
>> On 4/11/2012 6:38 AM, Kevin Rushforth wrote:
>>
>>> Sure, I could add something like that to make it more clear. Anything
>>> that causes the window to be no longer showing will cause showAndWait()
>>> to return, which includes calling hide() or closing the window through
>>> window system interaction.
>>>
>>> I just realized that there is something else I need to add to the
>>> documentation: nested calls are permitted, but an "outer" call to
>>> showAndWait() will never return until all "inner" calls return. This can
>>> happen in the following case:
>>>
>>> <SOME EVENT HANDLER> {
>>> s1.showAndWait(); // blocks until s1 is hidden
>>> some instruction after s1 is hidden
>>> }
>>>
>>> ...
>>>
>>> <SOME OTHER EVENT HANDLER> {
>>> s2.showAndWait(); // blocks until s2 is hidden
>>> some instruction after s2 is hidden
>>> }
>>>
>>> At this point you have a nested event loop within a nested event loop.
>>> If some piece of code calls "s1.hide()" it will not unblock and exit
>>> "some instruction after s1 is hidden" until s2 is also closed.
>>>
>>
>> this is exactly the problem we have in AWT/Swing: we don't strictly
>> specify our behavior for nested modal dialogs in our JavaDoc. It's good to
>> see JavaFX specification is (will be) better in this case :)
>>
>> However, it's not enough, even if we showAndWait s1 only, without s2.
>> Given that s1.hide() can only be called on JavaFX thread, it will likely be
>> in
>>
>> <SOME YET ANOTHER EVENT HANDLER> {
>>    s1.hide/close();
>>    some instructions here
>> }
>>
>> These instructions are executed before "some instruction after s1 is
>> hidden", despite s1.hide() has already been called. What's even worse,
>> there may be many code frames in the stack before the last event handler,
>> and all of them should be exited to proceed with the code after
>> s1.showAndWait().
>>
>> Thanks,
>>
>> Artem
>>
>>  -- Kevin
>>>
>>>
>>> Tom Schindl wrote:
>>>
>>>> What I'm not clear about is what are the circumstances the call returns.
>>>> Is it only when the user hits the stages close icon, someone calls the
>>>> close/hide method, ...?
>>>>
>>>> Maybe referring to close/hide in the javadoc makes it clear?
>>>>
>>>> So the revised javadoc could be:
>>>>
>>>> --
>>>> Show the stage and wait for it to be closed (through user interaction or
>>>> by calling {@link #close} or {@link #hide}) before returning to the
>>>> caller. This must be called on the FX Application thread. The stage must
>>>> not already be visible prior to calling this method. This must not be
>>>> called on the primary stage.
>>>> --
>>>>
>>>>
>>>> Tom
>>>>
>>>>
>>>>
>>>> Am 10.04.12 22:43, schrieb Kevin Rushforth:
>>>>
>>>>> JIRA: http://javafx-jira.kenai.com/**browse/RT-19783<http://javafx-jira.kenai.com/browse/RT-19783>
>>>>>
>>>>> We have had several requests for a way to block the caller while a
>>>>> (modal) dialog is shown. The show() method on a Stage is specified to
>>>>> return to the caller immediately regardless of the modality of a stage.
>>>>> This is a good semantic for many applications, but complicates the
>>>>> logic
>>>>> for other applications which don't want to proceed until the dialog is
>>>>> dismissed. It is also needed internally to implement an Alert class
>>>>> (see
>>>>> RT-12643 <http://javafx-jira.kenai.com/**browse/RT-12643<http://javafx-jira.kenai.com/browse/RT-12643>>
>>>>> for example).
>>>>> Swing dialog, for example, JOptionPane, work by blocking the caller
>>>>> until the dialog is dismissed meaning that Swing application
>>>>> programmers
>>>>> are already familiar with that model.
>>>>>
>>>>> Our proposal for JavaFX 2.2 is to add a new method on Stage,
>>>>> showAndWait(), which will block the caller until the stage is hidden.
>>>>> Note that while this is primarily useful for modal Stages, there is
>>>>> nothing in the API that restricts it to such.
>>>>>
>>>>> The proposed method and javadoc are described in the JIRA
>>>>> <http://javafx-jira.kenai.com/**browse/RT-19783?**
>>>>> focusedCommentId=110277&page=**com.atlassian.jira.plugin.**
>>>>> system.issuetabpanels:comment-**tabpanel#comment-110277<http://javafx-jira.kenai.com/browse/RT-19783?focusedCommentId=110277&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-110277>>,
>>>>>
>>>>>
>>>>> but since it is so short, I will also list it here:
>>>>>
>>>>> /**
>>>>> * Show the stage and wait for it to be closed before returning
>>>>> to the
>>>>> * caller. This must be called on the FX Application thread. The
>>>>> stage
>>>>> * must not already be visible prior to calling this method. This
>>>>> must not
>>>>> * be called on the primary stage.
>>>>> *
>>>>> * @throws IllegalStateException if this method is called on a
>>>>> thread
>>>>> * other than the JavaFX Application Thread.
>>>>> * @throws IllegalStateException if this method is called on the
>>>>> * primary stage.
>>>>> * @throws IllegalStateException if this stage is already showing.
>>>>> */
>>>>> public void showAndWait();
>>>>>
>>>>>
>>>>> -- Kevin
>>>>>
>>>>>
>>>>
>>>>


More information about the openjfx-dev mailing list