2011-07-30 29 views
6

Estoy intentando utilizar un SwingWorker para llevar a cabo una tarea larga y actualizar un JLabel con el resultado:Java GUI Congela incluso con SwingWorker

button.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     new SwingWorker<String, Void>() { 

      @Override 
      protected String doInBackground() throws Exception { 
       return doCalculation(); 
      } 

      protected void done() { 
       try { 
        label.setText(get()); 
       } catch (InterruptedException e) { 
        System.out.println("thread was interrupted"); 
       } catch (ExecutionException e) { 
        System.out.println("there was an ExecutionException"); 
       } 
      } 

     }.execute(); 

    } 

}); 

puedo hacer clic en el botón tantas veces como me gusta y el Gui seguirá siendo receptivo hasta que se terminen dos hilos, en cuyo punto el Gui se congela mientras se están ejecutando los hilos. Si solo ejecuto un hilo a la vez, este problema aún ocurre.

Estaría encantado si alguien pudiera indicarme si estoy utilizando el SwingWorker incorrectamente o si hay otro problema que desconozco. Gracias por tu tiempo. Ian

Editar

El doCalculation() es sólo algo que consume tiempo:

private String doCalculation() { 
    for (int i = 0; i < 10000000; i++) { 
     Math.pow(3.14, i); 
    } 
    return threads++ + ""; 
} 
+1

No veo nada obviamente mal con el código que ha publicado hasta ahora, pero creo que la clave aquí es qué está sucediendo en el método 'doCalculation();'. ¿Puedes publicar este código? –

Respuesta

6

Lo siento, pero incluso con su método de doCalculate(), todavía no soy capaz para reproducir tu problema Por ejemplo, aquí está mi sscce:

import java.awt.event.*; 
import java.util.concurrent.ExecutionException; 
import javax.swing.*; 

public class FooGui { 
    private static int threads = 0; 

    private static void createAndShowUI() { 
     final JLabel label = new JLabel("  "); 
     JButton button = new JButton("Button"); 
     button.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      new SwingWorker<String, Void>() { 

       @Override 
       protected String doInBackground() throws Exception { 
        return doCalculation(); 
       } 

       @Override 
       protected void done() { 
        try { 
        label.setText(get()); 
        } catch (InterruptedException e) { 
        System.out.println("thread was interrupted"); 
        } catch (ExecutionException e) { 
        System.out.println("there was an ExecutionException"); 
        } 
       } 
      }.execute(); 
     } 
     }); 
     JPanel panel = new JPanel(); 
     panel.add(button); 
     panel.add(label); 

     JFrame frame = new JFrame("FooGui"); 
     frame.getContentPane().add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    private static String doCalculation() { 
     for (int i = 0; i < 5000000; i++) { 
     Math.pow(3.14, i); 
     } 
     return threads++ + ""; 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      createAndShowUI(); 
     } 
     }); 
    } 
} 

Es posible que desee crear y publicar un "Short, Self Contained, Correct (Compilable), Example" or SSCCE de su cuenta (por favor, compruebe el enlace). Apuesto a que en el proceso de crear esto, probablemente usted mismo encuentre el problema y su solución. Si es así, asegúrese de volver aquí y háganos saber.

Sé que esto no es realmente una respuesta, pero no hay forma de publicar código como este en un comentario.

+1

Gracias por su ayuda, lo agradezco. Encontré el mismo congelamiento en tu ejemplo también, así que experimenté con él. Al ejecutar desde eclipse/línea de comando, se reproduce esto. Creé un jar ejecutable y funciona perfectamente. Estoy ejecutando Windows 7 de 64 bits. Lo intenté con Ubuntu y eso parece solucionar el problema también. Gracias de nuevo. – Ian

+0

Nunca lo veo dentro de Listener, no estoy seguro con put ..., pero tu publicación, probablemente sea posible, buen ejemplo, sin problemas de rendimiento +1 – mKorbel

+1

@Ian: Hm, aún sería bueno saber por qué ocurre la congelación en esas circunstancias particulares. Quizás tiene que ver con demasiados hilos. He oído que hay momentos en los que se deben tratar varios hilos cuando no se puede usar un SwingWorker, sino que se debe usar un ExecutorService y un grupo de subprocesos. –