Question

J'ai une interface utilisateur construit à l'intérieur d'un JFrame. L'un des boutons commence un long appel en cours d'exécution (toujours dans le même processus java), et pendant son exécution, l'interface utilisateur est gelé.

Je me suis dit, de faire comprendre que les choses sont encore en cours d'exécution, je peux afficher une barre de progression, peut-être dans une fenêtre contextuelle, de sorte que l'utilisateur peut être tenue à jour à ce que le programme est en train de faire.

Alors je crée une nouvelle JDialog, en ajoutant un JProgressBar à lui, et le mettre à jour que les choses se passent. Le problème est que le contenu de cette boîte de dialogue ne se mis à jour. Les changements que je fais à son titre montrer immédiatement, et tout ce que je sortie à la console, mais rien dans l'interface utilisateur lui-même.

Y at-il une commande que je peux émettre pour forcer un repeindre?

Voici le coeur de cette section:

  killWindow = new JDialog();
  killWindow.setUndecorated(true);
  killWindow.setTitle("stopping tests - 0 of " + numActive);
  killProgress = new JProgressBar(0, numActive);
  killWindow.add(killProgress);
  killProgress.setStringPainted(true);
  killWindow.pack();
  killWindow.setLocationRelativeTo(frame);
  killWindow.setVisible(true);

Alors, comme nous progressons ...:

  killProgress.setValue(++killedTests);                    // not seen!
  killProgress.setString("Killing test on " + nickname()); // not seen!
  log("Killed another test, " + killedTests + " so far");  // visible in real time
  killWindow.setTitle("stopping tests - " + killedTests +
                      " of " + killProgress.getMaximum()); // visible in real time

Qu'est-ce que je manque? J'ai essayé googler et de la recherche ici sur le SO, et ne l'ont pas vraiment vu quelque chose évidente?

Était-ce utile?

La solution

Vous devez effectuer votre longue tâche en cours d'exécution dans un autre thread.

Il y a ce fil appelé « AWT Dispatch événement discussion » qui est responsable de la mise à jour des composants de l'interface utilisateur. Si elle est en train d'effectuer votre tâche longue en cours, il pas mettre à jour l'interface utilisateur (ni vous rafraîchir dialogue).

Vous pouvez envisager d'utiliser SwingUtilities ou un SwingWorker .

De la documentation noreferrer"> du SwingWorker ici est un échantillon

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
   @Override
   public String doInBackground() {
       return findTheMeaningOfLife();
   }

   @Override
   protected void done() {
       try { 
           label.setText(get());
       } catch (Exception ignore) {
       }
   }
}

(new MeaningOfLifeFinder()).execute();

En exécutant votre tâche longue dans un autre thread, vous autorisez le fil événement AWT d'expédition pour montrer une interface utilisateur réactive.

Vous pouvez jeter un oeil à ce « Leçon de la Java tutoriel » pour mieux comprendre ces concepts.

Autres conseils

On dirait que vous pourriez exécuter votre tâche longue en cours d'exécution sur le fil Dispatch Event (HAE). Jetez un oeil à SwingWorker. Si vous utilisez 1.6, il est construit en:

http://java.sun.com /javase/6/docs/api/javax/swing/SwingWorker.html

Dans le cas contraire, vous pouvez trouver plus d'infos sur:

http://en.wikipedia.org/wiki/SwingWorker

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top