Java GUI зависает даже с SwingWorker - PullRequest
6 голосов
/ 30 июля 2011

Я пытаюсь использовать SwingWorker для выполнения длительной задачи и обновить JLabel с результатом:

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

    }

});

Я могу нажимать на кнопку сколько угодно раз, и графический интерфейс будет реагировать до тех пор, пока два потока не будут завершены, и в этот момент графический интерфейс зависнет во время работы потоков. Если я запускаю только один поток за раз, эта проблема по-прежнему возникает.

Я был бы рад, если бы кто-нибудь мог указать, неправильно ли я использую SwingWorker или есть другая проблема, о которой я не знаю. Спасибо за ваше время. Ian

Редактировать

doCalculation () просто требует много времени:

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

1 Ответ

6 голосов
/ 30 июля 2011

Извините, но даже с вашим методом doCalculate () я все еще не могу воспроизвести вашу проблему. Например вот мой 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();
         }
      });
   }
}

Вы можете создать и опубликовать «Короткое, Автономное, Правильное (Компилируемое), Пример» или SSCCE ) (пожалуйста, проверьте ссылку). Держу пари, что в процессе создания этого вы, вероятно, найдете проблему и ее решение самостоятельно. Если так, пожалуйста, вернитесь сюда и дайте нам знать.

Я знаю, что это не совсем ответ, но нет способа опубликовать такой код в комментарии.

...