2012-01-18 15 views
8

Tengo una etiqueta de mensaje y un botón de envío. El botón de enviar se presionará varias veces, y la acción para cada pulsación puede tomar hasta un minuto.Swing - Etiqueta de actualización

Cuando se presiona el botón, deseo configurar el mensaje como vacío y, una vez completada la tarea, deseo configurar el mensaje como "Completo".

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

    doTheTask(); 

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

¿Es posible actualizar la etiqueta de mensaje antes de ejecutar el método submitActionPerformed() (o en el método), pero después de hacer clic en el botón?

+2

que podría estar infiriendo demasiado aquí, pero casi parece una barra de progreso que funcionaría muy bien aquí (http://docs.oracle. com/javase/tutorial/uiswing/components/progress.html)? –

+0

@ ZackMacomber ese es el siguiente paso –

Respuesta

10

sí se puede hacer esto utilizando SwingWorker hilo, hacer todas las actividades pre submitActionPerformed() como actualizar la etiqueta, en el método de la currentThreadexecute() y llame doTheTask() como un trabajo en segundo plano usando trabajador Thread.

le sugiero que vaya a través de esta documentación de referencia sobre SwingWorker Thread

+2

Lo mejor es vincular a la última versión de los JavaDocs. He editado su respuesta para que apunte a J2SE 7. Para obtener sugerencias sobre cómo obtener un enlace a los últimos documentos, consulte [punto 2 de ventajas] (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7090875) . –

13

Aunque el Swing concurrency tutorial ya contiene algunas muy buenas muestras sobre cómo hacer frente a la concurrencia en Swing, se encuentran por debajo de un ejemplo que

  • contiene una casilla de verificación para probar la interfaz de usuario sigue vivo
  • tiene una barra de progreso, que se actualiza a partir de la SwingWorker
  • tiene una etiqueta, que se actualiza a la vez finalizada SwingWorker

    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

gracias por el código. muy útil. –

+3

la implementación del proceso no está funcionando del todo como pueden esperar los usuarios: pueden ser varios (acumulados) valores en la lista, pero está estableciendo el valor de la barra de progreso en el primero. En su lugar, recorra todo o use el último punto – kleopatra

+0

@kleopatra. Voy a ajustar el código – Robin

Cuestiones relacionadas