Swing – Actualizar etiqueta

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

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

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 esa etiqueta de mensaje antes de submitActionPerformed() método submitActionPerformed() (o en el método), pero después de hacer clic en el botón?

Sí, puedes hacer esto usando el subproceso SwingWorker , hacer todas las actividades pre submitActionPerformed() como actualizar la etiqueta, en el método execute() del doTheTask() y llamar doTheTask() como un trabajo en segundo plano usando worker Thread .

Le sugiero que revise esta documentación para referencia sobre el tema SwingWorker

Aunque el tutorial de concurrencia de Swing ya contiene algunas muestras muy buenas sobre cómo lidiar con la concurrencia en Swing, busque a continuación un ejemplo que

  • contiene una checkbox para demostrar que la IU sigue viva
  • tiene una barra de progreso, que se actualiza desde el SwingWorker
  • tiene una etiqueta, que se actualiza una vez que el SwingWorker está terminado

     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{ 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 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(); } } } }