|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||
Workaround for the following problem with modal dialogs.
Warning:
If you don't know what this is about you should not touch the code -
neither the implementation of this interface nor the code that uses it.
Problem:
When a modal dialog is shown, most ui toolkits have a blocking method call, i.e. the opening "show" does not return until the dialog has been closed again.
If you want to execute some code right after the modal dialog has been opened (but before the dialog has been closed again) you can not write that code after the blocking statement (that includes the "show" since that code is executed after the dialog has been closed already. Furthermore you can't give that code to the "show" call to execute right after the opening of the dialog since (usually) the ui toolkit does not support that.
In case you have to make several calls, i.e. activate components that are related to a dialog, and you don't have any clue if one of them (and which one) contains a blocking call you are faced with the problem that some calls to "activate" would be executed after the dialog has already been closed. That kind of messes up any attempts to have an ordered life cycle.
Solution:
Usually (assumption 1) ui toolkits provide a possibility to "inject" an event into the ui's system event queue that is executed some time later.
Usually (assumption 2) ui toolkits handle modal dialogs by creating a new active event queue once the dialog has been shown. That event queue is active until the dialog has been closed. When the dialog closes the calls unwind and the original call to "show" returns. The events from the current event queue are taken to the new event queue und executed there.
With the following trick it is possible to allow the seamless execution of individual jobs regardless of one job making a blocking call:
com.sdm.quasar.client.core.common.util.JobQueue#isFinished()If none of the jobs contains a blocking call, the queue is completely executed in the second loop. When the first loop is finally processed by the event queue, it find that all the work is already done.
If one of the jobs contains a blocking call, the queue is executed up to that call in the second loop. Then the modal dialog is opened and the second event queue is started. The second event queue processes the queued events, and one of them is the first loop we've added to it. The first loop processes the remaining jobs in the queue. After the dialog closes the blocking call returns and the second loop resumes work only to find that everything is finished.
The code typically looks like this:
public void startJob( JobQueue jobQueue) {
UIToolKit.MethodThatInjectsAnEventForProcessingItLater(
{
while (!jobQueue.isFinished()) {
jobQueue.doNextJob();
}
}
);
while (!jobQueue.isFinished()) {
jobQueue.doNextJob();
}
}
In implementing ModalBlockHelperService.JobQueue.doNextJob()
you should take care that the blocking call is the last statement executed in the method
since any statements after the blocking call will be executed after the modal dialog
has been closed. This workaround does only apply to the jobs queued after the blocking
job, not to statements after the blocking statement within the same job.
This will not work (and thus this interface will be useless in those cases) when the ui toolkit does not act according to the assumptions (1) and (2) made above.
Implementations of this class must do the correct thing for the corresponding ui toolkit.
| Nested Class Summary | |
static interface |
ModalBlockHelperService.JobQueue
Defines a job queue whose work is portioned in single jobs. |
| Method Summary | |
void |
startJob(ModalBlockHelperService.JobQueue jobQueue)
Executes the individual jobs in the ModalBlockHelperService.JobQueue
until it is finished (ModalBlockHelperService.JobQueue.isFinished().
|
| Method Detail |
public void startJob(ModalBlockHelperService.JobQueue jobQueue)
ModalBlockHelperService.JobQueue
until it is finished (ModalBlockHelperService.JobQueue.isFinished().
If one of the jobs (ModalBlockHelperService.JobQueue.doNextJob() makes
a blocking call that starts another event queue
(e.g. a modal dialog is shown) the remaining jobs are executed
within the new event queue.
See ModalBlockHelperService for more information and
a description of what should happen in the implementation.
jobQueue - the job queue to be processed
|
|||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||