Java News from Monday, November 24, 2003

Tip of the day: if you need a modal dialog that blocks input to the parent frame but does not block the current thread, just show the dialog in a newly created thread like so:

            Thread dontBlockMe = new Thread(new Runnable() {
                public void run() {
                    modalDialog.show();                    
                }
            });
            dontBlockMe.start();

Downside to this approach: depending on circumstances there can be a subtle race condition here. The dialog should not be hidden until after the dialog is shown on the screen. This isn't a problem if the only way for the dialog to be hidden is for the user to dismiss it explicitly since they won't be able to do so until it's drawn. However, in my case I was using this for a progress dialog that could vanish without user intervention very quickly in some (not all, and not reproducible) circumstances. I couldn't join the main thread to dontBlockMe because it doesn't exit until the dialog disappears. I couldn't use wait() and notify() because dontBlockMe blocks until the dialog is hidden. Solution: poll the dialog every 50 milliseconds until you're sure it's on the screen:

            while (!(modalDialog.isVisible())) {
                try {
                    wait(50);   
                }
                catch (InterruptedException ex) {
                    // try again
                }
            }

This seems to work. It brings up a modal dialog without blocking the main thread, and does not allow the main thread to continue until the dialog is shown. (Normal behavior for modal dialogs is not to allow the thread to continue until the dialog is hidden.) However, I'm still nervous about it. Threads are tricky. It needs more testing on different systems. Does anybody see anything wrong with this? Complete code is part of the QueryFrame class in XQuisitor.