Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swing - Update Label

I have a message label and a submit button. The submit button will be pressed multiple times, and the action for the each press can take up to a minute.

When the button is pressed, I want to set the message to empty, and after the task is complete, I want to set the message to "Complete".

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

   doTheTask();

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

Is it possible to update that message label before the submitActionPerformed() method is run (or in the method), but after the the button is clicked?

like image 709
Berek Bryan Avatar asked Jan 18 '12 20:01

Berek Bryan


People also ask

How do I update labels in Java?

To update the text in a label you use label. setText("New text") .

How do I add labels in swing?

JLabel() : creates a blank label with no text or image in it. JLabel(String s) : creates a new label with the string specified. JLabel(Icon i) : creates a new label with a image on it. JLabel(String s, Icon i, int align) : creates a new label with a string, an image and a specified horizontal alignment.

How do you change a JLabel name?

The JLabel is an object, the name you assign that data type will make the mapping between the memory allocated in the Heap and the object self, if you want to change the name, then re allocate the object by creating a new one, with a new variable name.


2 Answers

Although the Swing concurrency tutorial already contains some very good samples on how to deal with concurrency in Swing, find below an example which

  • contains a checkbox to prove the UI is still alive
  • has a progress bar, which gets updated from the SwingWorker
  • has a label, which gets updated once the SwingWorker is finished

    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();
          }
        }
      }
    }
    
like image 160
Robin Avatar answered Oct 02 '22 20:10

Robin


Yes you can do this using SwingWorker thread, do all the pre submitActionPerformed() activities like updating the label, in the execute() method of the currentThread and call doTheTask() as a background job using worker Thread.

I suggest you to go through this documentation for reference about SwingWorker Thread

like image 30
Rajesh Pantula Avatar answered Oct 02 '22 20:10

Rajesh Pantula