Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java GUI Freezes even with SwingWorker

I'm trying to use a SwingWorker to perform a lengthy task and update a JLabel with the result:

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

    }

});

I can click the button many times as I like and the Gui will remain responsive until two threads are finished at which point the Gui freezes while threads are running. If I only run one thread at a time, this problem still occurs.

I'd be greatful if anyone could point out if I am using the SwingWorker incorrectly or if there is another problem I'm not aware of. Thanks for your time. Ian

Edit

The doCalculation() is just something time consuming:

private String doCalculation() {
    for (int i = 0; i < 10000000; i++) {
        Math.pow(3.14, i);
    }
    return threads++ + "";
}
like image 311
Ian Avatar asked Jul 30 '11 14:07

Ian


1 Answers

I'm sorry, but even with your doCalculate() method, I'm still not able to reproduce your problem. For example here is my 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();
         }
      });
   }
}

You may wish to create and post a "Short, Self Contained, Correct (Compilable), Example" or SSCCE of your own (please check the link). I'll bet that in the process of creating this, you'll probably find the problem and its solution yourself. If so, please be sure to come back here and let us know.

I know that this is not really an answer, but there's no way to post code like this in a comment.

like image 76
Hovercraft Full Of Eels Avatar answered Sep 28 '22 07:09

Hovercraft Full Of Eels