Java的invokeLater

SwingUtilities.invokeLater() 是 Java Swing 库中的一个方法,用于确保一个任务可以在稍后的某个时间在事件分发线程(Event Dispatch Thread, EDT)上执行。EDT 负责处理 GUI 事件,包括绘图和事件监听器的调用。在 Swing 应用程序中,所有的组件更新和操作通常需要在这个线程上完成,以避免线程安全问题。

下面是 invokeLater 的一个基本用法示例:

import javax.swing.SwingUtilities;

public class Example {

    public static void main(String[] args) {
        // 创建一个 Runnable 对象,其 run 方法包含了需要在事件分发线程中执行的代码
        Runnable task = new Runnable() {
            public void run() {
                // 这里是需要在事件分发线程后续某个时刻执行的代码
                // 例如,创建和显示一个 GUI 界面
            }
        };

        // 使用 SwingUtilities.invokeLater 来安排这个任务在事件分发线程中执行
        SwingUtilities.invokeLater(task);
    }
}

在这个例子中,我们创建了一个 Runnable 对象,然后通过 invokeLater 方法将其传递给事件分发线程来安排未来的执行。这个方法通常在以下场景中使用:

  1. 从非事件分发线程更新 GUI:如果你在一个不是 EDT 的线程中,并且你需要更新 GUI,那么你应该使用 invokeLater 来请求这些更新在 EDT 上执行。
  2. 应用程序启动:在应用程序的 main 方法中,当你需要创建和显示 GUI,invokeLater 可以用来确保 GUI 创建的动作在正确的线程中执行。

invokeLater 方法的另一个好处是,它可以帮助避免潜在的竞态条件。如果有多个线程试图同时更新 GUI,使用 invokeLater 可以将这些更新排队,从而按顺序在 EDT 上执行,避免了不一致和不可预测的行为。

请注意,如果你在 EDT 上调用 invokeLater,传递的任务仍然会被排队并稍后执行,这可能会导致事件处理的微小延迟。

从 Java 8 开始,你可以使用 lambda 表达式来简化上面的代码:

SwingUtilities.invokeLater(() -> {
    // 这里是需要在事件分发线程后续某个时刻执行的代码
    // 例如,创建和显示一个 GUI 界面
});

总之,SwingUtilities.invokeLater() 是一个实用的工具,用于确保代码块在 Swing 的事件分发线程上异步执行,这对于维护 Swing 应用程序的线程安全至关重要。



 

这里有一个简单的 Java Swing 程序示例,它使用 SwingUtilities.invokeLater 来确保 GUI 的创建和更新在事件分发线程(EDT)上执行。该程序将创建一个简单的窗口(JFrame)并在其中显示一个标签(JLabel)。

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class SwingExample {

    // 创建并显示 GUI 的方法
    private static void createAndShowGUI() {
        // 创建 JFrame 实例
        JFrame frame = new JFrame("Swing Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建一个标签并添加到 JFrame 中
        JLabel label = new JLabel("Hello, Swing!");
        frame.getContentPane().add(label);

        // 设置窗口大小
        frame.setSize(300, 200);
        // 显示窗口
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // 使用 SwingUtilities.invokeLater 来确保 GUI 创建的动作在事件分发线程中执行
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

在这个示例中,定义了 createAndShowGUI 方法,用于设置 GUI。在 main 方法中通过 invokeLater 来调用 createAndShowGUI,从而确保 GUI 的创建和显示是在 EDT 上完成的。

运行这些命令后,你应该会看到一个小窗口,其中有文本 "Hello, Swing!"。

现在将上面的代码使用 Java 8 的 lambda 表达式进行简化:

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class SwingExample {

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Swing Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel("Hello, Swing!");
        frame.getContentPane().add(label);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // 使用 lambda 表达式简化 Runnable 的实现
        SwingUtilities.invokeLater(() -> createAndShowGUI());
    }
}

这个程序的功能与之前的示例相同,只是使用了 lambda 表达式来替代匿名内部类,使代码更加简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值