Bạn chỉ cần miễn phí chuỗi chủ đề của một số tác vụ nặng và thực hiện chúng trong một chuỗi riêng biệt. Trong trường hợp đó, hoạt ảnh gif sẽ hoạt động cùng với các quá trình khác đang chạy.
Bạn cũng có thể tạo giao diện ứng dụng của mình trong một chuỗi riêng biệt (có, không phải bên trong EDT) nhưng chỉ cho đến khi bạn hiển thị nó. Sau đó bạn phải thực hiện tất cả các thay đổi bên trong EDT, nếu không bạn có thể gặp phải rất nhiều vấn đề.
Bạn cũng có thể tải thêm phần tử giao diện người dùng trong một chuỗi riêng biệt sau này, chỉ cần đảm bảo rằng bạn thêm chúng vào khung/vùng hiển thị bên trong EDT - đó là điều quan trọng nhất.
Dưới đây là một ví dụ nhỏ của "nặng giống như" giao diện tải:
public static void main (String[] args) throws InvocationTargetException, InterruptedException
{
// Main window
final JFrame frame = new JFrame();
final JPanel panel = new JPanel (new FlowLayout (FlowLayout.LEFT, 5, 5))
{
public Dimension getPreferredSize()
{
Dimension ps = super.getPreferredSize();
ps.width = 0;
return ps;
}
};
frame.add (new JScrollPane (panel));
frame.setSize (600, 500);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo (null);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
frame.setVisible (true);
}
});
// Load dialog
final JDialog load = new JDialog (frame);
JPanel panel2 = new JPanel (new BorderLayout());
panel2.setBorder (BorderFactory.createEmptyBorder (15, 15, 15, 15));
load.add (panel2);
final JProgressBar progressBar = new JProgressBar (0, 100);
panel2.add (progressBar);
load.setModal (false);
load.pack();
load.setLocationRelativeTo (frame);
SwingUtilities.invokeAndWait (new Runnable()
{
public void run()
{
load.setVisible (true);
}
});
// Heavy task (takes approx. 10 seconds + some time on buttons creation)
for (int i = 0; i < 100; i++)
{
Thread.sleep (100);
final JButton button = new JButton ("Button" + i);
final int finalI = i;
// Updating panel and progress in EDT
SwingUtilities.invokeLater (new Runnable()
{
public void run()
{
panel.add (button);
button.revalidate();
progressBar.setValue (finalI);
}
});
}
}
Như bạn có thể nhìn thấy - tất cả các hoạt động cập nhật giao diện được thực hiện trong EDT, mọi thứ khác chạy bên trong các chủ đề khác.
Cũng lưu ý rằng chủ đề chính không phải là chuỗi EDT, vì vậy chúng tôi có thể làm điều gì đó nặng ở đó ngay lập tức.
Trong một số trường hợp, nó không cần thiết để hiển thị các phần được tải của giao diện ngay lập tức, vì vậy bạn có thể thêm chúng hoàn toàn vào cuối hoạt động "nặng". Điều đó sẽ tiết kiệm thời gian tải và sẽ làm cho mã khởi tạo đơn giản hơn nhiều.
giải thích tóm tắt về EDT và những gì tôi đã nói trong câu trả lời ...
...nó là cái gì tôi tìm thấy sau khi làm việc ba năm dưới Swing L & F và rất nhiều ứng dụng dựa trên Swing. Tôi đào rất nhiều nguồn Swing và tìm thấy rất nhiều điều thú vị mà không được biết đến rộng rãi.
Như bạn đã biết - toàn bộ ý tưởng về chuỗi đơn cho bản cập nhật giao diện (EDT của nó trong Swing) là giữ mỗi thành phần riêng biệt trực quan cập nhật (và sự kiện của nó) trong hàng đợi và thực hiện từng cái một . Điều đó là cần thiết chủ yếu để tránh các vấn đề về sơn vì mọi thành phần bên trong một khung hình được vẽ lên ảnh đơn được lưu giữ trong bộ nhớ. Thứ tự sơn là nghiêm ngặt ở đó nên một thành phần sẽ không ghi đè lên hình ảnh cuối cùng khác. Thứ tự sơn phụ thuộc vào cây thành phần được tạo ra bằng cách thêm một số thành phần hoặc thùng chứa bên trong một vùng chứa khác (đó là điều cơ bản bạn thực hiện khi tạo bất kỳ giao diện ứng dụng nào trên Swing).
Để tóm tắt - bạn phải giữ tất cả trực quan cập nhật (phương pháp/hoạt động có thể gây ra chúng) bên trong EDT. Bất cứ điều gì khác có thể được thực hiện bên ngoài EDT - ví dụ bạn có thể chuẩn bị giao diện ứng dụng bên ngoài EDT (một lần nữa, trừ khi bạn thêm/xóa/di chuyển thành phần bên trong một vùng chứa đã hiển thị).
Vẫn còn có thể có một số vấn đề nội bộ với điều đó trong một số trường hợp rất rất rất hiếm. Đã có một cuộc thảo luận tốt của câu hỏi đó một thời gian dài trước đây:
http://www.velocityreviews.com/forums/t707173-why-does-jdk-1-6-recommend-creating-swing-components-on-the-edt.html
Để có ngắn: từ 6 phiên bản JDK Sun ghi trong tài liệu mà ngay cả Swing thành phần tạo nên được thực hiện bên EDT để tránh thể vấn đề. Chúng có thể xuất hiện trong một số trường hợp cụ thể với việc tạo giao diện nặng do các sự kiện xảy ra trong khi các thành phần được tạo ra.
Dù sao, tôi muốn nói rằng trong một số trường hợp, bạn có thể tạo giao diện bên ngoài EDT để tránh trình tải/ứng dụng bị kẹt. Trong các trường hợp khác, khi nó không quan trọng nếu ứng dụng bị mắc kẹt cho thời gian tạo giao diện - bạn nên sử dụng EDT. Và tôi không thể nói bất cứ điều gì cụ thể hơn vì mọi thứ phụ thuộc vào trường hợp của bạn ...
Xem xét sử dụng một [màn hình splash] (http://docs.oracle.com/javase/tutorial/uiswing/misc/splashscreen.html) thay vì nếu nó là dành cho khởi nghiệp ứng dụng của bạn – Robin