Pregunta

Tengo una interfaz de usuario construida dentro de un jframe. Uno de los botones comienza una llamada larga (todavía dentro del mismo proceso de Java), y durante su ejecución, la interfaz de usuario está congelada.

Pensé que para dejar en claro que las cosas aún se están ejecutando, puedo mostrar una barra de progreso, tal vez en una ventana emergente, para que el usuario pueda mantenerse actualizado sobre lo que está haciendo el programa.

Así que estoy creando un nuevo JDialog, agregando un JProgressbar a él y actualizándolo a medida que las cosas suceden. El problema es que el contenido de ese diálogo no se actualiza. Los cambios que hago en su título aparecen de inmediato, y cualquier cosa que envíe a la consola, pero nada en la UI en sí.

¿Hay algún comando que pueda emitir para forzar un repintado?

Aquí está el núcleo de esta sección:

  killWindow = new JDialog();
  killWindow.setUndecorated(true);
  killWindow.setTitle("stopping tests - 0 of " + numActive);
  killProgress = new JProgressBar(0, numActive);
  killWindow.add(killProgress);
  killProgress.setStringPainted(true);
  killWindow.pack();
  killWindow.setLocationRelativeTo(frame);
  killWindow.setVisible(true);

Entonces, a medida que avanzamos ...:

  killProgress.setValue(++killedTests);                    // not seen!
  killProgress.setString("Killing test on " + nickname()); // not seen!
  log("Killed another test, " + killedTests + " so far");  // visible in real time
  killWindow.setTitle("stopping tests - " + killedTests +
                      " of " + killProgress.getMaximum()); // visible in real time

¿Qué me estoy perdiendo? Intenté buscar en Google y buscar aquí, ¿y realmente no he visto algo obvio?

¿Fue útil?

Solución

Tienes que realizar tu tarea de carrera larga en otro hilo.

Existe este hilo llamado "hilo de despacho de eventos AWT" que está a cargo de la actualización de los componentes de la interfaz de usuario. Si está ocupado realizando su tarea de larga ejecución, no Actualice la interfaz de usuario (ni actualice su diálogo).

Puede considerar usar Swingutilidad o Swingworker.

Del swingworker documentación Aquí hay una muestra

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
   @Override
   public String doInBackground() {
       return findTheMeaningOfLife();
   }

   @Override
   protected void done() {
       try { 
           label.setText(get());
       } catch (Exception ignore) {
       }
   }
}

(new MeaningOfLifeFinder()).execute();

Al ejecutar su tarea larga en un hilo diferente, está permitiendo que el hilo de despacho de eventos AWT muestre una interfaz de usuario receptiva.

Puedes echar un vistazo a esto "Lección del tutorial de Java"Para comprender mejor estos conceptos.

Otros consejos

Parece que podría estar ejecutando su tarea de larga duración en el hilo de despacho de eventos (EDT). Echa un vistazo al swingworker. Si está utilizando 1.6 está integrado:

http://java.sun.com/javase/6/docs/api/javax/swing/swingworker.html

Si no, puede encontrar más información en:

http://en.wikipedia.org/wiki/swingworker

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top