2009-11-18 4 views
0

J'ai une applet qui appelle un JDialog qui contient un composant JProgressBar. Je la sous-classe JDialog pour exposer une méthode pour mettre à jour le JProgressBar, quelque chose comme:L'applet avec JDialog ne se cache pas correctement sous Mac OSX

public class ProgressDialog extends javax.swing.JDialog { 
    public void setProgress(double progress) { 
     jProgressBar1.setValue(jProgressBar1.getMinimum() + (int) (progress * jProgressBar1.getMaximum())); 
    } 
    ... 
} 

J'utilise cette boîte de dialogue de la manière suivante:

public void test() throws Exception { 
    progressDialog = new ProgressDialog(null, true); 

    try { 
     progressDialog.setLocationRelativeTo(null); 

     // show the dialog 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       progressDialog.setVisible(true); 
      } 
     }); 

     // business logic code that calls progressDialog.setProgress along the way 
     doStuff(); 

    } finally { 
     progressDialog.setVisible(false); 
     progressDialog.dispose(); 
    } 
} 

Il fonctionne très bien sur Windows/ne importe quel navigateur. Toutefois, lorsque vous invoquez la fonction ci-dessus sur Firefox 2/3/3.5 sur un Mac, le ProgressDialog est affiché indéfiniment, c'est-à-dire qu'il ne se ferme pas.

Je me doutais bien que l'appel setVisible (vrai) à l'intérieur du EventQueue était à l'origine du problème, car il est un appel de blocage et peut bloquer la file d'attente complètement, donc j'ai essayé de changer à:

 // show the dialog 
     new Thread() { 
      public void run() { 
       progressDialog.setVisible(true); 
      } 
     }.start(); 

Avec ce changement, ProgressDialog se ferme maintenant correctement, mais un nouveau problème est apparu: le contenu de la boîte de dialogue (qui incluait la barre de progression, une icône et un JLabel utilisé pour afficher une chaîne de message) n'apparaissait plus dans la boîte de dialogue. C'était toujours un problème uniquement sur Mac Firefox.

Des idées? Je me rends compte que c'est probablement un problème de filetage AWT, mais je suis là depuis quelques jours et je ne trouve pas de bonne solution. Envelopper la logique métier doStuff() dans un nouveau thread distinct semble fonctionner, mais il n'est pas facile de refactoriser le code de la logique métier en un thread séparé, donc j'espère qu'il existe une solution plus simple.

Le ENVT est: Mac OSX 10.5 Java 1.5 Firefox 2/3/3,5

Répondre

1

a découvert que le problème était que la fonction de l'applet exécutait à l'intérieur du fil de répartiteur AWT, par conséquent, les blocs de fil et pas les événements sont traités jusqu'à ce que la fonction de l'applet termine l'exécution.

La solution consistait à déplacer la logique de traitement dans un thread distinct engendré par l'objet ProgressDialog avant d'appeler setVisible (true). setVisible (true) bloquerait le thread principal tout en permettant au répartiteur d'événements de poursuivre le traitement, rendant ainsi le contenu du dialogue jusqu'à ce que le thread engendré appelle setVisible (false) pour masquer le dialogue.