2010-06-10 29 views
9

Trong Java, để tạo ra và hiển thị một mới JFrame, tôi chỉ đơn giản làm điều này:Tại sao người ta chạy Java GUI trên Queue Event

public static void main(String[] args) { 
    new MyCustomFrameClass().setVisible(true); 
} 

Tuy nhiên, tôi đã thấy nhiều người làm việc đó như thế này:

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new MyCustomFrameClass().setVisible(true); 
     } 
    }); 
} 

Tại sao? Có lợi thế nào không?

Trả lời

8

Quy tắc điều chỉnh những gì cần được thực hiện trên EDT (Tôi thấy "EDT" thường được sử dụng hơn "Hàng đợi sự kiện") đã thay đổi trong suốt thời gian tồn tại của Java. Và mỗi khi "quy tắc" thay đổi, Sun khuyên bạn nên làm nhiều hơn và nhiều hơn nữa "GUI liên quan" làm việc trên EDT.

Tại sao mọi người chạy Java GUI trên EDT?

  • Vì nguyên tắc chính thức khuyên bạn nên làm như vậy.

  • Vì làm như vậy sẽ giúp tránh nhiều lỗi luồng liên quan đến GUI.

Note, và đây không phải là rất nổi tiếng, rằng EDT thực không sụp đổ một lần trong một thời gian, vì Swing chính nó có một vài lỗi. Mỗi ứng dụng Swing không tầm thường đều sử dụng các API Swing có, tốt, các lỗi và do đó một lần trong một thời gian EDT chết.

Bạn không bao giờ nhìn thấy nó và nó không phải là một nguyên nhân của mối quan tâm, bởi vì khi EDT chết nó được tự động khởi động lại.

Về cơ bản, hãy thực hiện tất cả các nội dung liên quan đến GUI trên EDT và thực hiện tất cả các hoạt động lenghty bên ngoài EDT (để không chặn EDT).

EDIT bạn đã yêu cầu một ví dụ về cách chạy một hoạt động lenghty bên ngoài EDT. Có nhiều hướng khác nhau để làm điều đó. Trong trường hợp đơn giản nhất, bạn chỉ cần tạo và bắt đầu một Thread mới, từ EDT. Dưới đây là một ví dụ: gọi lại nghe được gọi khi người dùng nhấp vào một nút, chúng ta biết rằng điều này sẽ xảy ra trên EDT ...

JButton jb = ... 
    jb.addActionListener(new ActionListener() { 
     public void actionPerformed(final ActionEvent e) { 
      final Thread t = new Thread(new Runnable() { 
      public void run() { 
      // this shall get executed, after start() has been called, outside the EDT  
      } 
      }); 
      t.start(); 
     } 
    }); 

Đối với ví dụ phức tạp hơn, bạn muốn đọc trên SwingWorker , v.v.

+0

Làm cách nào để thực hiện các hoạt động ngoài EDT nếu chúng cần được bắt đầu từ GUI của tôi? (sự kiện nút, vv) Ngoài ra, tôi có cần sử dụng EDT chỉ cho khung chính không? Nếu người dùng mở một JFrame khác từ khung chính (ví dụ một cửa sổ tùy chọn), tôi có cần khởi động nó trên EDT không? – asmo

+0

@asmo: Tôi sẽ chỉnh sửa câu hỏi của mình để đưa ra ví dụ – NoozNooz42

+0

@asmo: bạn cần công việc trên EDT cho * mọi thứ * liên quan đến GUI (vì vậy trong * "cửa sổ tùy chọn" * ví dụ, yup, cần cũng được thực hiện trên EDT nữa). – NoozNooz42

4

Dòng này được sửa đổi một thành phần Swing từ khung tùy chỉnh của bạn là một lớp con của JFrame:

new MyCustomFrameClass().setVisible(true); 

Nói chung, bạn không bao giờ nên thay đổi một thành phần Swing trừ khi bạn đang ở trên Chủ đề tổ chức sự kiện văn (EDT).

Mã sau sẽ chạy bất kỳ nội dung nào trong số Runnable trên EDT.

EventQueue.invokeLater(Runnable); 

Bây giờ, cuộc gọi setVisible(true) sẽ có trên EDT như bình thường.

+0

Tôi muốn tạo một thể hiện của một lớp con JFrame chứ không phải trực tiếp một JFrame. Xin lỗi vì sự nhầm lẫn.(Tôi đã cập nhật bài đăng gốc) – asmo

+0

Điều tương tự vẫn áp dụng cho bất kỳ lớp con nào của bất kỳ thành phần swing nào. Nó không thay đổi gì cả. (@asmo) – jjnguy

+0

Cảm ơn bạn đã làm rõ. – asmo

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