2012-01-18 5 views
8

Ho un'etichetta di messaggio e un pulsante di invio. Il pulsante di invio verrà premuto più volte e l'azione per ciascuna stampante può richiedere fino a un minuto.Swing - Etichetta di aggiornamento

Quando si preme il pulsante, desidero impostare il messaggio su vuoto e, al termine dell'attività, desidero impostare il messaggio su "Completa".

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

    doTheTask(); 

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

E 'possibile aggiornare l'etichetta che il messaggio prima che il metodo submitActionPerformed() viene eseguito (o nel metodo), ma dopo che il pulsante viene cliccato?

+2

potrei inferire troppo qui, ma sembra quasi una barra di avanzamento avrebbe funzionato bene qui (http://docs.oracle. com/JavaSE/tutorial/uiswing/componenti/progress.html)? –

+0

@ZackMacomber che rappresenta il passaggio successivo –

risposta

10

Sì, è possibile farlo usando SwingWorker discussione, fare tutte le pre submitActionPerformed() attività come l'aggiornamento dell'etichetta, nel metodo della currentThreadexecute() e chiamare doTheTask() come processo in background utilizzando lavoratore Thread.

vi consiglio di passare attraverso questa documentazione di riferimento su SwingWorker Thread

+2

È preferibile collegarsi all'ultima versione di JavaDocs. Ho modificato la risposta in modo che punti a J2SE 7. Per suggerimenti su come ottenere un collegamento agli ultimi documenti, vedere [punto 2 dei vantaggi] (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7090875) . –

13

Anche se il Swing concurrency tutorial contiene già alcuni ottimi esempi su come affrontare la concorrenza in Swing, riporta qui di seguito un esempio che

  • contiene una casella di controllo per provare l'interfaccia utente è ancora vivo
  • ha una barra di avanzamento, che viene aggiornato dal SwingWorker
  • ha un'etichetta, che viene aggiornato una volta che il SwingWorker è finito

    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

grazie per il codice. molto utile. –

+3

l'implementazione del processo non funziona come ci si aspetterebbe dagli utenti: i loro potrebbero essere diversi (accumulati) valori nell'elenco, ma sta impostando il valore progressBar solo sul primo. Al contrario, puoi eseguire il loop di tutto o utilizzare l'ultimo solo – kleopatra

+0

@kleopatra. Regolerò il codice – Robin