awt - How to display Java dialog using alternate event queue? -


i have code detects if java awt event queue frozen (busy processing event or waiting lock) excessive amount of time, due buggy foreign code fails use swingworker or similar, , want offer recover. killing event dispatch thread thread.stop works, hazardous (and eq might blocked because computer temporarily overloaded), prefer prompt user confirmation. displaying dialog requires waiting eq unblocked, not possible.

is there way, reasonably portable java program, display dialog (or kind of ui element can respond input events) without involving normal event queue?

i tried running systemtray.add(trayicon), manage display tray item when called thread... icon not painted, , actionevents not delivered, not helpful.

it seems possible display new jframe , paint label on using paintimmediately, there still no apparent way receive mouse events.

following tom hawtin's hint, tried create new appcontext. on jdk 6u18, dialog shown in new context seems paint correctly not receive mouse events until main event queue unblocked, defeating purpose:

import java.awt.eventqueue; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.util.map; import java.util.concurrent.executors; import java.util.concurrent.scheduledexecutorservice; import java.util.concurrent.timeunit; import javax.swing.jbutton; import javax.swing.jdialog; import javax.swing.jframe; import javax.swing.windowconstants; import sun.awt.appcontext; import sun.awt.suntoolkit; public class main {     public static void main(string[] args) {         eventqueue.invokelater(new runnable() {             public @override void run() {                 new mainwindow().setvisible(true);                 system.err.println("main context: " + appcontext.getappcontext());             }         });         new trackeq(1000*3);     }     private static class mainwindow extends jframe {         mainwindow() {             setdefaultcloseoperation(windowconstants.exit_on_close);             jbutton pause = new jbutton("pause");             pause.addactionlistener(new actionlistener() {                 public @override void actionperformed(actionevent e) {                     try {                         thread.sleep(15000);                     } catch (interruptedexception x) {                         x.printstacktrace();                     }                 }             });             getcontentpane().add(pause);             pack();             setlocation(100, 100);         }     }     private static class trackeq implements runnable {         private final scheduledexecutorservice svc;         private final int timeout;         private boolean stuck = false;         private boolean wait = false;         private thread eq;         trackeq(int timeout) {             this.timeout = timeout;             svc = executors.newsinglethreadscheduledexecutor();             svc.schedule(this, 0, timeunit.milliseconds);         }         public @override synchronized void run() {             if (eventqueue.isdispatchthread()) {                 stuck = false;                 eq = thread.currentthread();             } else {                 if (stuck && !wait) {                     system.err.println("ui stuck!");                     wait = true;                     map<thread,stacktraceelement[]> stacktraces = thread.getallstacktraces();                     stacktraceelement[] stack = stacktraces.get(eq);                     if (stack != null) {                         (stacktraceelement el : stack) {                             system.err.println("stuck @ " + el);                         }                         threadgroup grp = new threadgroup("showing dialog");                         grp.setdaemon(true);                         new thread(grp, new runnable() {                             public @override void run() {                                 system.err.println("created new app context in " + thread.currentthread().getthreadgroup());                                 suntoolkit.createnewappcontext();                                 eventqueue.invokelater(new runnable() {                                     public @override void run() {                                         system.err.println("main eq=" + eq + " whereas eq=" + thread.currentthread());                                         system.err.println("will show dialog in " + appcontext.getappcontext());                                         final jdialog dlg = new jdialog();                                         dlg.setdefaultcloseoperation(windowconstants.dispose_on_close);                                         jbutton fix = new jbutton("fix!");                                         fix.addactionlistener(new actionlistener() {                                             @suppresswarnings("deprecation")                                             public @override void actionperformed(actionevent e) {                                                 system.err.println("agreed fix");                                                 eq.stop();                                                 wait = false;                                                 dlg.setvisible(false);                                             }                                         });                                         dlg.getcontentpane().add(fix);                                         dlg.pack();                                         dlg.setlocation(200, 100);                                         dlg.setvisible(true);                                         system.err.println("showed dialog");                                     }                                 });                             }                         }, "showing dialog").start();                     } else {                         system.err.println("no stack trace " + eq + "; listed threads: " + stacktraces.keyset());                     }                 } else {                     stuck = true;                 }                 eventqueue.invokelater(this);                 svc.schedule(this, timeout, timeunit.milliseconds);             }         }     }     private main() {} } 

the awt apis written if there event queue. talking mutable statics , hence bad design , evil hacks.

the sun plugin , webstart use undocumented api hack in context. check out appcontext class. context looked first threadgroup and, if inconclusive, examining classloaders on stack.

obvious comments: of course run separate process. application make sure don't block critical resources including edt.


Comments

Popular posts from this blog

c++ - Convert big endian to little endian when reading from a binary file -

C#: Application without a window or taskbar item (background app) that can still use Console.WriteLine() -

unicode - Are email addresses allowed to contain non-alphanumeric characters? -