views:

64

answers:

1

Hi,

I have a Java/Swing desktop application (Java 6u16 on Windows XP) which occasionally appears to the users to hang. I say appears to because in reality what is happening is that the application is showing a modal dialog but this dialog is not being rendered. If the user uses Alt-Tab to switch away from the application and then subsequently returns to it, the dialog gets rendered correctly. Additionally, if a remote user connects to the session via NetOp (a VNC/Remote Desktop workalike) this also causes the GUI to be redrawn correctly.

The app runs via JavaWebstart. Since I've heard of rendering issues being caused by DirectDraw, I added the following to the JNLP

<property name="sun.java2d.noddraw" value="true"/>

but the problem still occurs (If I have understood correctly, this will switch off DirectDraw and Direct3d completely: see http://download.oracle.com/javase/1.5.0/docs/guide/2d/flags.html#noddraw)

I'm out of ideas on this one, any suggestions would be greatly appreciated.

Thanks,
Phil

Edit...

I have an abstract dialog class which extends JDialog and which all other dialogs extend. It contains the following method:

public void showDialog() {      
    initKeyBindings();
    Application.getApplication().deactivateScannerListener();
    setVisible(true);
}

Whenever I want to display a dialog, I call showDialog(). The initKeyBindings method sets up an ActionMap while the second line is application specific (Application is a singleton, I'm disabling the JPOS scanner listener while the dialog is displaying).

There is a corresponding hideDialog() method as follows:

public void hideDialog() {      
    setVisible(false);
    Application.getApplication().activateScannerListener();
    dispose();
}

Thanks, Phil

Edit... Sorry about this, one more edit: all of the dialogs have a parent. The AbstractDialog class will default to the main application frame if no other parent is specified.

FYI For anyone following this, I've added the following to my code:

if (SwingUtilities.isEventDispatchThread()) {
        initialiseAndShowDialog();
} else {
    SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
               initialiseAndShowDialog();
            }
    });
}

This ensures that the dialog is only opened from the EDT.

+2  A: 

Which thread are you calling showDialog() from? Swing components should be accessed on the Event Dispatch Thread only.

You could try SwingUtilities.invokeAndWait() and the Runnable argument passed to it should call showDialog().

Let us know if it fixed the problem.

Ustaman Sangat
Hi Ustamnan, normally showDialog() would be invoked from the EDT but it's a pretty large application so it could be there are some occurrances of showDialog() being invoked from another thread. Based on your suggestion, I can adjust showDialog() so that it uses SwingUtilities.invokeAndWait() thus guaranteeing that the processing takes place on EDT. I won't know for a while if this resolves the issue but I'm sure it won't hurt. Thanks.
PhilDin
What about just printing the thread name from showDialog()? Maybe when you notice that the Dialog box doesn't show unless refreshed (e.g. by ALT+TAB as you mentioned), you could then check if it was called from a different thread. I guess running the app in debug mode is not an option as u said the problem occurs *occasionally* only.
Ustaman Sangat
For the benefit of anyone following this, I modified showDialog() and hideDialog() so that they call invokeAndWait() if they are not on the EDT (I've added sample code to the question). They also log the fact that this has occurred. Based on this change, I can see a few places where the dialogs were being opened from threads other than EDT so it has probably helped but hasn't actually resolved the issue. I'll keep looking other EDT violations.
PhilDin
To anyone experiencing similar problems, I've used this http://frequal.com/java/SwingThreadDebugging.html to identify EDT violations.
PhilDin