Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Tầm quan trọng của lớp SwingUtilities trong Java

Trong Java, sau khi các thành phần Swing hiển thị trên màn hình, chúng chỉ có thể được thao tác bởi một luồng duy nhất gọi là Event Dispatch Thread (EDT) - Luồng xử lý sự kiện. Chúng ta có thể viết code trong một khối riêng biệt và chuyển tham chiếu khối này cho EDT. Lớp SwingUtilities cung cấp hai phương thức tĩnh quan trọng: invokeAndWait() và invokeLater() để đưa các khối code vào hàng đợi sự kiện (event queue).

Cú pháp

public static void invokeAndWait(Runnable doRun) throws InterruptedException, InvocationTargetException 
public static void invokeLater(Runnable doRun)

Tham số doRun là tham chiếu đến một instance của interface Runnable. Ở đây, interface Runnable không được truyền vào constructor của Thread. Nó đơn giản được dùng để xác định điểm vào (entry point) cho luồng sự kiện. Tương tự như luồng mới gọi run(), luồng sự kiện sẽ gọi phương thức run() khi đã xử lý xong các sự kiện khác đang chờ trong hàng đợi. Ngoại lệ InterruptedException được ném ra nếu luồng gọi invokeAndWait() hoặc invokeLater() bị ngắt trước khi khối code hoàn thành. Ngoại lệ InvocationTargetException được ném ra nếu có ngoại lệ không được bắt trong phương thức run().

Ví dụ minh họa

import javax.swing.*; 
import java.lang.reflect.InvocationTargetException; 

public class SwingUtilitiesTest { 
    public static void main(String[] args) { 
        final JButton button = new JButton("Not Changed"); 
        JPanel panel = new JPanel(); 
        panel.add(button); 
        JFrame f = new JFrame("InvokeAndWaitMain"); 
        f.setContentPane(panel); 
        f.setSize(300, 100); 
        f.setVisible(true); 
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        
        System.out.println(Thread.currentThread().getName() + " is going into sleep for 3 seconds"); 
        try { 
            Thread.sleep(3000); 
        } catch(Exception e){ } 
        
        // Chuẩn bị code thay đổi nhãn
        Runnable r = new Runnable() { 
            @Override 
            public void run() { 
                System.out.println(Thread.currentThread().getName() + " is going into sleep for 10 seconds"); 
                try { 
                    Thread.sleep(10000); 
                } catch(Exception e){ } 
                button.setText("Button Text Changed by " + Thread.currentThread().getName()); 
                System.out.println("Button changes ended"); 
            } 
        }; 
        
        System.out.println("Component changes put on the event thread by main thread"); 
        try { 
            SwingUtilities.invokeAndWait(r); 
        } catch (InvocationTargetException | InterruptedException e) { 
            e.printStackTrace(); 
        } 
        System.out.println("Main thread reached end"); 
    } 
}

Kết quả đầu ra

Chương trình minh họa việc luồng chính (main thread) nhờ luồng EDT cập nhật giao diện. Nút bấm sẽ thay đổi văn bản sau 10 giây trên luồng EDT, trong khi luồng chính chờ đợi (invokeAndWait) cho đến khi hoàn tất.