2010-08-06 4 views
1

J'essaie d'utiliser des threads pour exécuter une opération longue durée en arrière-plan et mettre à jour l'interface utilisateur. Voici ce que je suis en train de faire:Problème de thread Java - mise à jour de l'interface graphique

  1. sur un bouton clic, afficher un popupjframe avec un message « insertion dans DB »
  2. créer un nouveau thread pour insérer 1000s d'entrées dans une base de données.
  3. lorsque les entrées sont insérées, je veux le popupjframe disparaître et afficher un JOptionPane avec oui, pas de boutons
  4. sur en cliquant sur le bouton Oui, je veux afficher un autre cadre avec un rapport/détails sur le processus d'insertion

Voici mon code:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
//display popupframe first 

jFrame1.pack(); 
jFrame1.setVisible(true); 
jFrame1.setLocationRelativeTo(getFrame()); 
Thread queryThread = new Thread() { 
public void run() { 
runQueries(); 
}}; 
queryThread.start(); 
} 

//runqueries method inserts into DB

private void runQueries() { 
for (int i = 0; i <= 50000; i++) { 
insertintoDB(); 
updateProgress(i); 
} 
} 

//update the popupjframe 
private void updateProgress(final int queryNo) { 
SwingUtilities.invokeLater(new Runnable() { 
public void run() { 
if (queryNo == 50000) { //means insertion is done 
jFrame1.setVisible(false); 

int n = JOptionPane.showConfirmDialog(getFrame(), menuBar, null, JOptionPane.YES_NO_OPTION); 

if (n == 1) { //NO option was selected 
return;} 
else 
//display another popupframe with details/report of inserting process 
}}); 
} 
  1. Mon approche est-elle correcte?
  2. Comment et quand dois-je arrêter/interrompre le "queryThread" ??
  3. Est-il correct si je fais le popupjframe dans la méthode runqueries lui-même (après la boucle for) et affiche le joptionpane ??

Merci d'avance.

+0

Dans votre méthode runQueries(), vous appelez UpdateProgress() 50000 fois, chaque fois que la création d'un nouveau thread, alors que seul le dernier il faut faire un travail utile. Ce n'est peut-être pas lourd, mais ce sont des frais généraux inutiles et, au mieux, des codes trompeurs. Et ILMTitan est correct: SwingWorker est la bonne façon d'y aller. –

Répondre

4

Consultez la documentation de SwingWorker. Il fait exactement ce que vous essayez de faire. Créez une sous-classe et appelez runQueries à partir de doInBackground(), puis faites ce que fait votre runnable (moins la vérification if queryNo) dans done(). Il existe des versions tierces de cette classe si vous n'utilisez pas java 1.6.

class DbSwingWorker extends SwingWorker<Void, Integer> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     for (int i = 0; i <= 50000; i++) { 
      insertintoDB(); 
      publish(i); //if you want to do some sort of progress update 
     } 
     return null; 
    } 

    @Override 
    protected void done() { 
     int n = JOptionPane.showConfirmDialog(getFrame(), menuBar, null, JOptionPane.YES_NO_OPTION); 

     if (n == 1) { //NO option was selected 
      return; 
     } else { 
      //display another popupframe with details/report of inserting process 

     } 
    } 
} 

L'original, la version non-1.6 est disponible ici: https://swingworker.dev.java.net/

+0

Voir aussi . –

Questions connexes