java - invokeAndWait seems to cause the application to freeze intermittently -


a process occurs in background fires callbacks ask various questions.

in case question "is okay migrate data?", have ask user. since have swing work on edt, ends looking (i removed comments, reference our own convenience methods , parameters allowmigration() - other that, else same):

public class usermigrationacceptor implements migrationacceptor {     private final window ownerwindow;     public usermigrationacceptor(window ownerwindow) {         this.ownerwindow = ownerwindow;     }      // called on background worker thread     @override     public boolean allowmigration() {         final atomicboolean result = new atomicboolean();         try {             swingutilities.invokeandwait(new runnable() {                 @override                 public void run() {                     result.set(askuser());                 }             });         } catch (interruptedexception e) {             thread.currentthread.interrupt();             return false;         } catch (invocationtargetexception e) {             throw throwables.propagate(e.getcause());         }         return result.get();     }      // called on edt     private boolean askuser() {         int answer = joptionpane.showconfirmdialog(ownerwindow, "...", "...",                                                    joptionpane.ok_cancel_option);         return answer == joptionpane.ok_option;     } } 

what's happening in situations, after confirming or cancelling dialog appears, swing seems following state:

  • the joptionpane no longer visible
  • there nothing pending on event queue
  • the background thread stuck inside #invokeandwait, waiting invocationevent#isdispatched() return true.

are doing wrong here, or looking @ bug in swing/awt?

the other thing might worth noting second level of modal dialogs. there modal dialog showing progress of operation , confirmation dialog has progress dialog parent.

update 1: here's edt blocked:

java.lang.thread.state: waiting       @ sun.misc.unsafe.park(unsafe.java:-1)       @ java.util.concurrent.locks.locksupport.park(locksupport.java:186)       @ java.util.concurrent.locks.abstractqueuedsynchronizer$conditionobject.await(abstractqueuedsynchronizer.java:2043)       @ java.awt.eventqueue.getnextevent(eventqueue.java:543)       @ java.awt.eventdispatchthread.pumponeeventforfilters(eventdispatchthread.java:211)       @ java.awt.eventdispatchthread.pumpeventsforfilter(eventdispatchthread.java:161)       @ java.awt.eventdispatchthread.pumpeventsforfilter(eventdispatchthread.java:154)       @ java.awt.waitdispatchsupport$2.run(waitdispatchsupport.java:182)       @ java.awt.waitdispatchsupport$4.run(waitdispatchsupport.java:221)       @ java.security.accesscontroller.doprivileged(accesscontroller.java:-1)       @ java.awt.waitdispatchsupport.enter(waitdispatchsupport.java:219)       @ java.awt.dialog.show(dialog.java:1082)       @ java.awt.component.show(component.java:1651)       @ java.awt.component.setvisible(component.java:1603)       @ java.awt.window.setvisible(window.java:1014)       @ java.awt.dialog.setvisible(dialog.java:1005)       @ com.acme.swing.progress.jprogressdialog$statechangelistener$1.run(jprogressdialog.java:200)       @ java.awt.event.invocationevent.dispatch(invocationevent.java:251)       @ java.awt.eventqueue.dispatcheventimpl(eventqueue.java:733)       @ java.awt.eventqueue.access$200(eventqueue.java:103)       @ java.awt.eventqueue$3.run(eventqueue.java:694)       @ java.awt.eventqueue$3.run(eventqueue.java:692)       @ java.security.accesscontroller.doprivileged(accesscontroller.java:-1)       @ java.security.protectiondomain$1.dointersectionprivilege(protectiondomain.java:76)       @ java.awt.eventqueue.dispatchevent(eventqueue.java:703)       @ java.awt.eventdispatchthread.pumponeeventforfilters(eventdispatchthread.java:242)       @ java.awt.eventdispatchthread.pumpeventsforfilter(eventdispatchthread.java:161)       @ java.awt.eventdispatchthread.pumpeventsforfilter(eventdispatchthread.java:154)       @ java.awt.waitdispatchsupport$2.run(waitdispatchsupport.java:182)       @ java.awt.waitdispatchsupport$4.run(waitdispatchsupport.java:221)       @ java.security.accesscontroller.doprivileged(accesscontroller.java:-1)       @ java.awt.waitdispatchsupport.enter(waitdispatchsupport.java:219)       @ java.awt.dialog.show(dialog.java:1082)       @ javax.swing.joptionpane.showoptiondialog(joptionpane.java:870) 

what's odd here showoptiondialog() @ bottom migration prompt, dialog#setvisible further progress dialog. in other words, somehow child dialog appears before parent, , perhaps breaking swing.

update 2:

and indeed, can make happen in test program without using of our own code. although dialog positioning different in test program, hangs in same way, more reproducibly. gist

i had same issue in own code.

your call joptionpane.showoptiondialog() never returns, because while event dispatch loop sitting there waiting user input, timer (or else) has fired , caused modal dialog install own event loop. in stack, culprit jprogressdialog$statechangelistener$1.run(), can see launch own event dispatch loop.

until jprogressdialog closed, won't exit loop, , earlier call joptionpane.showoptiondialog() never return.

this might not obvious if dialog parents seem imply hierarchy isn't honored event queue.

two solutions might either avoid modal progress dialog, or show progress dialog immediately. launching modal dialog off event going idea if rest of event thread happy sit , wait closed.


Comments

Popular posts from this blog

html5 - What is breaking my page when printing? -

c# - must be a non-abstract type with a public parameterless constructor in redis -

ajax - PHP/JSON Login script (Twitter style) not setting sessions -