2011-07-30 3 views
6

Tôi đang cố gắng sử dụng một SwingWorker để thực hiện một nhiệm vụ dài và cập nhật một JLabel với kết quả:Java GUI đông đặc ngay cả với SwingWorker

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

    } 

}); 

tôi có thể nhấp vào nút nhiều lần như tôi thích và Gui sẽ vẫn đáp ứng cho đến khi hai luồng được hoàn thành tại thời điểm mà Gui bị đóng băng trong khi các luồng đang chạy. Nếu tôi chỉ chạy một luồng tại một thời điểm, vấn đề này vẫn xảy ra.

Tôi sẽ rất tuyệt nếu có ai có thể chỉ ra nếu tôi đang sử dụng SwingWorker không chính xác hoặc nếu có một vấn đề khác mà tôi không biết. Cảm ơn vì đã dành thời gian cho tôi. Ian

Sửa

Các doCalculation() chỉ là một cái gì đó tốn thời gian:

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

Tôi không thấy bất cứ điều gì rõ ràng là sai với mã bạn đã đăng cho đến nay, nhưng tôi nghĩ chính ở đây là những gì đang diễn ra trong phương thức 'doCalculation();'. Bạn có thể gửi mã này không? –

Trả lời

6

Tôi xin lỗi, nhưng ngay cả với phương pháp doCalculate() của bạn, tôi vẫn không thể để tái tạo vấn đề của bạn. Ví dụ ở đây là tôi 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(); 
     } 
     }); 
    } 
} 

Bạn có thể muốn tạo và đăng "Short, Self Contained, Correct (Compilable), Example" or SSCCE của riêng bạn (hãy kiểm tra các liên kết). Tôi sẽ đặt cược rằng trong quá trình tạo ra điều này, bạn có thể sẽ tự tìm ra vấn đề và giải pháp của nó. Nếu có, vui lòng quay lại đây và cho chúng tôi biết.

Tôi biết rằng đây không thực sự là câu trả lời, nhưng không có cách nào để đăng mã như thế này trong một nhận xét.

+1

Cảm ơn bạn đã giúp đỡ, tôi đánh giá cao nó. Tôi tìm thấy cùng một đóng băng trong ví dụ của bạn cũng như vậy tôi đã thử nghiệm với nó. Chạy từ eclipse/dòng lệnh sao chép này. Tôi tạo ra một cái bình runnable và nó chạy hoàn hảo. Tôi đang chạy Windows 64-bit 7. Tôi đã thử nó với Ubuntu và có vẻ như để khắc phục vấn đề là tốt. Cảm ơn một lần nữa. – Ian

+0

Tôi không bao giờ thấy rằng bên trong Trình nghe, tôi không chắc chắn với việc đặt ..., nhưng bài đăng của bạn, đó là cách có thể, ví dụ hay, không có vấn đề về hiệu suất +1 – mKorbel

+1

@Ian: Hm, nó sẽ vẫn tuyệt vời biết tại sao sự đóng băng xảy ra trong những hoàn cảnh nhất định. Có lẽ nó phải làm với quá nhiều chủ đề. Tôi đã nghe nói rằng có lần khi giao dịch với nhiều chủ đề khi bạn không thể sử dụng một SwingWorker nhưng thay vào đó sẽ cần phải sử dụng một ExecutorService và một hồ bơi thread. –