2012-01-18 3 views
8

J'ai une étiquette de message et un bouton d'envoi. Le bouton de soumission sera pressé plusieurs fois, et l'action pour chaque pression peut prendre jusqu'à une minute.Swing - Libellé de mise à jour

Lorsque le bouton est enfoncé, je veux définir le message à vide, et une fois la tâche terminée, je veux définir le message sur "Terminé".

private void submitActionPerformed(java.awt.event.ActionEvent evt) { 
    message = ""; 
    updateMessageLabel(); 

    doTheTask(); 

    /* this update is apply to the label after completion */ 
    message = "Complete"; 
} 

Est-il possible de mettre à jour cette étiquette de message avant que la méthode submitActionPerformed() est exécutée (ou dans la méthode), mais après le clic sur le bouton?

+2

je pourrais être déduis trop ici, mais semble presque comme une barre de progression fonctionnerait bien ici (http://docs.oracle. com/javase/tutoriel/uiswing/components/progress.html)? –

+0

@ZackMacomber est la prochaine étape –

Répondre

10

Oui, vous pouvez le faire en utilisant un fil SwingWorker, faire toutes les activités pré submitActionPerformed() comme la mise à jour de l'étiquette, dans la méthode execute() du currentThread et appeler doTheTask() comme un travail de fond en utilisant travailleur Thread.

Je vous suggère de passer par cette documentation pour référence sur SwingWorker Thread

+2

Il est préférable de créer un lien vers la dernière version de JavaDocs. J'ai édité votre réponse pour pointer vers J2SE 7. Pour obtenir des conseils sur l'obtention d'un lien vers les derniers documents, voir [point 2 des avantages] (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7090875) . –

13

Bien que le Swing concurrency tutorial contient déjà quelques très bons exemples sur la façon de traiter avec la concurrence dans Swing, trouverez ci-dessous un exemple qui

  • contient une case à cocher pour prouver que l'interface utilisateur est toujours en vie
  • a une barre de progression, qui est mise à jour à partir du SwingWorker
  • a une étiquette qui est mise à jour une fois que le SwingWorker est terminé

    import javax.swing.JCheckBox; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JProgressBar; 
    import javax.swing.SwingWorker; 
    import java.awt.BorderLayout; 
    import java.awt.EventQueue; 
    import java.lang.reflect.InvocationTargetException; 
    import java.util.List; 
    import java.util.concurrent.ExecutionException; 
    
    public class SwingWorkerExample { 
        private static JProgressBar PROGRESS_BAR; 
        private static JLabel OUTPUT_LABEL; 
        private static JFrame createGUI(){ 
        JFrame testFrame = new JFrame("TestFrame"); 
    
        PROGRESS_BAR = new JProgressBar(); 
        PROGRESS_BAR.setMinimum(0); 
        PROGRESS_BAR.setMaximum(100); 
    
        OUTPUT_LABEL = new JLabel("Processing"); 
    
        testFrame.getContentPane().add(PROGRESS_BAR, BorderLayout.CENTER); 
        testFrame.getContentPane().add(OUTPUT_LABEL, BorderLayout.SOUTH); 
    
        //add a checkbox as well to proof the UI is still responsive 
        testFrame.getContentPane().add(new JCheckBox("Click me to proof UI is responsive"), BorderLayout.NORTH); 
    
    
    
        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        return testFrame; 
        } 
    
        public static void main(String[] args) throws InvocationTargetException, InterruptedException { 
        EventQueue.invokeAndWait(new Runnable() { 
         @Override 
         public void run() { 
         JFrame frame = createGUI(); 
    
         frame.pack(); 
         frame.setVisible(true); 
         } 
        }); 
        //start the SwingWorker outside the EDT 
        MySwingWorker worker = new MySwingWorker(PROGRESS_BAR, OUTPUT_LABEL); 
        worker.execute(); 
        } 
        private static class MySwingWorker extends SwingWorker<String, Double>{ 
        private final JProgressBar fProgressBar; 
        private final JLabel fLabel; 
        private MySwingWorker(JProgressBar aProgressBar, JLabel aLabel) { 
         fProgressBar = aProgressBar; 
         fLabel = aLabel; 
        } 
    
        @Override 
        protected String doInBackground() throws Exception { 
         int maxNumber = 10; 
         for(int i = 0; i < maxNumber; i++){ 
         Thread.sleep(2000);//simulate long running process 
         double factor = ((double)(i+1)/maxNumber); 
         System.out.println("Intermediate results ready"); 
         publish(factor);//publish the progress 
         } 
         return "Finished"; 
        } 
    
        @Override 
        protected void process(List<Double> aDoubles) { 
         //update the percentage of the progress bar that is done 
         int amount = fProgressBar.getMaximum() - fProgressBar.getMinimum(); 
         fProgressBar.setValue((int) (fProgressBar.getMinimum() + (amount * aDoubles.get(aDoubles.size() - 1)))); 
        } 
    
        @Override 
        protected void done() { 
         try { 
         fLabel.setText(get()); 
         } catch (InterruptedException e) { 
         e.printStackTrace(); 
         } catch (ExecutionException e) { 
         e.printStackTrace(); 
         } 
        } 
        } 
    } 
    
+0

merci pour le code. très utile. –

+3

L'implémentation du processus ne fonctionne pas comme les utilisateurs peuvent s'y attendre: leur valeur peut être plusieurs (accumulée) dans la liste, mais elle ne définit que la valeur de la progressBar. Au lieu de cela, soit en boucle à travers tout ou utiliser le seul bon point – kleopatra

+0

@kleopatra. Je vais ajuster le code – Robin

Questions connexes