2010-02-18 51 views
5

Tôi tự hỏi nếu SwingWorker phải là một lớp lồng trong GUI chính của tôi. Tôi muốn làm cho nó một lớp bên ngoài để giữ cho GUI rõ ràng từ bất kỳ logic chương trình của tôi.SwingWorker có phải là một lớp lồng nhau không?

Tôi đã cố gắng tạo lớp bên ngoài SwingWorker, hoạt động tốt cho quy trình, rất tiếc là tôi không thể truy cập bất kỳ trường GUI nào của mình từ lớp SwingWorker. Bất cứ khi nào tôi cố gắng truy cập vào một thuộc tính, chẳng hạn như nhãn hoặc bất kỳ thứ gì từ bên trong phương thức done() của SwingWorker, tôi nhận được một ngoại lệ nullPointer.

Mọi lời khuyên sẽ được đánh giá cao!


Trước hết cảm ơn bạn rất nhiều Jeff! Hoạt động tốt cho đến nay, mặc dù tôi không thể theo dõi bạn vào tùy chọn thứ hai mà bạn đã trình bày. Một trong các tác vụ nền của tôi tính toán một kích thước nhất định (giá trị dài), vì vậy sẽ rất tuyệt khi nhận được giá trị đó từ GUI của tôi.

Bạn đề xuất làm việc với getters và setters nhưng tiếc là tôi không có ý tưởng về cách triển khai chúng trong lớp SwingWorker.

Tôi đã thử nó như thế này:

public void setSize(long totalSize) { 
    this.totalSize = totalSize; 
} 
public long getTotalSize() { 
    return totalSize; 
} 

Các setter được gọi ở phần cuối của phương pháp doInBackground(). Rất tiếc, tôi không thể sử dụng phương thức get() từ GUI của mình.

final MySwingWorker w = new MySwingWorker(); 
Runnable r = new Runnable() { 
    public void run() { 
     // do something with w.get() 
    } 
}; 
w.setRunnable(r); 
w.execute(); 

Tạo đối tượng "w" không hoạt động trong trường hợp của tôi khi hàm tạo yêu cầu đối tượng Runnable. Tôi có thiếu gì đó không? Xin hãy dễ dàng với tôi, đây là lần đầu tiên tôi làm việc với SwingWorker. :) Một lần nữa, cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn!

Trả lời

6

Bạn có thể đặt SwingWorker thành lớp bên ngoài. Tuy nhiên, giống như bất kỳ lớp nào khác, nếu không thể thấy các biến (ví dụ: nhãn bạn muốn đặt), tất nhiên nó sẽ không thể đặt nó. Một điều bạn có thể làm là chuyển công nhân một Runnable mà nó thực thi khi nó hoàn tất.

public class MySwingWorker extends SwingWorker { 

    private final Runnable r; 
    public MySwingWorker(Runnable r) { 
     this.r = r; 
    } 
    public void doInBackground() {...} 
    public void done() { r.run(); } 
} 

Bây giờ từ GUI, bạn có thể làm điều gì đó như

Runnable updateLabel = new Runnable() { 
     public void run() { 
      label.setText("myValue"); 
     } 
}; 
SwingWorker w = new MySwingWorker(updateLabel); 
w.execute(); 

này được một chút phức tạp hơn nếu bạn muốn sử dụng kết quả của SwingWorker, mặc dù nó là có thể. Thay vì đi qua các Runnable để xây dựng các công nhân đu, bạn sẽ có một phương pháp setter và sau đó nó sẽ là một cái gì đó như:

final MySwingWorker w = new MySwingWorker(); 
Runnable r = new Runnable() { 
    public void run() { 
     // do something with w.get() 
    } 
}; 
w.setRunnable(r); 
w.execute(); 

Trong cả hai trường hợp, Runnable đang hoạt động tương tự như một đóng được thực hiện khi người lao động đã hoàn thành.

+0

Cũng có thể chỉ cần chuyển Nhãn trong hàm tạo chứ không phải runnable. Việc xác định một phân lớp công nhân mới cho mỗi hành động nhỏ có lẽ sẽ là quá mức cần thiết. Các lớp ẩn danh là tuyệt vời để giải quyết vấn đề cụ thể này khi đặt cùng một đối tượng kết hợp chặt chẽ và rất nhỏ. –

+0

Nó thực sự phụ thuộc nếu đây là một trường hợp sử dụng duy nhất. Sự trừu tượng hoạt động nếu bạn đang làm nó ở nhiều nơi. Oh cách đóng cửa sẽ hữu ích. –

Các vấn đề liên quan