2010-09-15 6 views
1

J'ai une application de bureau Java/Swing (Java 6u16 sous Windows XP) qui semble parfois être bloquée par les utilisateurs. Je dis semble à parce qu'en réalité ce qui se passe est que l'application montre un dialogue modal mais ce dialogue n'est pas rendu. Si l'utilisateur utilise Alt-Tab pour quitter l'application et y revient par la suite, la boîte de dialogue s'affiche correctement. En outre, si un utilisateur distant se connecte à la session via NetOp (un travail similaire à VNC/Remote Desktop), l'interface graphique est également redessinée correctement.Problème de rendu avec l'application Swing et les boîtes de dialogue modales

L'application fonctionne via JavaWebstart. Depuis que je l'ai entendu parler de problèmes de rendu causés par DirectDraw, j'ajouté ce qui suit à la JNLP

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

mais le problème persiste (Si je comprends bien, cela éteint DirectDraw et Direct3D complètement: voir http://download.oracle.com/javase/1.5.0/docs/guide/2d/flags.html#noddraw Je n'ai pas d'idées sur celui-ci, toutes les suggestions seraient grandement appréciées.

Merci,
Phil

Modifier ...

j'ai une classe de dialogue abstraite qui étend JDialog et que tous les autres boîtes de dialogue s'étendent. Il contient la méthode suivante:

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

Chaque fois que je veux afficher une boîte de dialogue, j'appelle showDialog(). La méthode initKeyBindings configure un ActionMap tandis que la deuxième ligne est spécifique à l'application (Application est un singleton, je désactive l'écouteur du scanner JPOS pendant l'affichage de la boîte de dialogue).

Il existe une méthode hideDialog() correspondant comme suit:

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

Merci, Phil

Modifier ... Désolé à ce sujet, un plus modifier: tous les les boîtes de dialogue ont un parent. La classe AbstractDialog sera définie par défaut sur le cadre de l'application principale si aucun autre parent n'est spécifié.

Pour votre information Pour tous ceux qui suivent, j'ai ajouté ce qui suit à mon code:

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

Cela garantit que le dialogue est ouvert uniquement de l'EDT.

+1

Pouvez-vous afficher le code qui provoque l'affichage de la boîte de dialogue modale? –

+0

Salut Vincent, merci de votre intérêt. J'ai modifié le post pour contenir un peu plus de détails. – PhilDin

Répondre

2

Quel fil appelez-vous showDialog() à partir de? Les composants Swing doivent être accessibles uniquement sur le thread Dispatch d'événement.

Vous pouvez essayer SwingUtilities.invokeAndWait() et l'Runnable l'argument passé à il devrait appeler showDialog(). Faites-nous savoir si le problème a été résolu.

+0

Salut Ustamnan, normalement showDialog() serait invoqué à partir de l'EDT, mais il s'agit d'une application assez volumineuse, donc il pourrait y avoir des occurrences de showDialog() invoqué à partir d'un autre thread. Sur la base de votre suggestion, je peux ajuster showDialog() pour qu'il utilise SwingUtilities.invokeAndWait() garantissant ainsi que le traitement se déroule sur EDT. Je ne saurai pas pendant un moment si cela résout le problème, mais je suis sûr que cela ne fera pas de mal. Merci. – PhilDin

+0

Qu'en est-il juste d'imprimer le nom du thread depuis showDialog()? Peut-être que lorsque vous remarquez que la boîte de dialogue n'apparaît pas à moins d'être actualisée (par exemple, par ALT + TAB comme vous l'avez mentionné), vous pouvez ensuite vérifier si elle a été appelée à partir d'un thread différent. Je suppose que l'exécution de l'application en mode débogage n'est pas une option car vous avez dit que le problème se produit * occasionnellement * seulement. –

+0

Pour le bénéfice de tous ceux qui suivent cela, j'ai modifié showDialog() et hideDialog() afin qu'ils appellent invokeAndWait() s'ils ne sont pas sur l'EDT (j'ai ajouté un exemple de code à la question). Ils enregistrent également le fait que cela s'est produit. Sur la base de ce changement, je peux voir quelques endroits où les dialogues ont été ouverts à partir de threads autres que EDT, donc cela a probablement aidé mais n'a pas réellement résolu le problème. Je continuerai à chercher d'autres violations de l'EDT. – PhilDin

Questions connexes