Swing 并发和事件调度线程

Swing concurrency and Event-Dispatch Thread

我想知道正确使用 java 挥杆的最可接受的方法是什么。我知道在 java swing 应用程序中默认有两个线程 Main Thread 和 Event-Dispatch。我以这种方式创建并显示 window 。

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> new MyWindow().initializeAndShow());
    }

但我想知道如何在 运行 时间内使用 java 摆动。我的意思是,例如在单击按钮时在 JText 中设置文本。我需要一直这样做吗?

  SwingUtilities.invokeLater(()-> button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e)
            {

               SwingUtilities.invokeLater(()-jtext.setText("HelloFromAWTThread");
            }
        });      

是否正确,我认为按钮也是 UI 的一部分,因此应该在调度线程中设置侦听器,或者这不正确? 并且设置 JText 也应该在 AWT 线程中?

没有你想的那么简单

当然,UI 元素的修改(e.h。设置标签文本,向按钮添加侦听器等)只能由事件分发线程 (EDT) 完成.

但大多数时候这并不是真正的限制,因为所有事件(例如鼠标单击按钮或按键)都由 EDT 处理,因此您的侦听器也在 EDT 上执行。

所以如果你想注册一个监听器,就这样

button.addActionListener(new ActionListener() {
    /* called by the EDT when the button has been clicked */
    public void actionPerformed(ActionEvent e) {
        jtext.setText("HelloFromAWTThread");
    }
});

或者使用 Java 8 个 lambda 表达式更简单:

button.addActionListener(e -> jtext.setText("HelloFromAWTThread"));

如果您想 运行 一项长期 运行 宁任务,它只会变得更加复杂,例如一个耗时的计算(计算 PI 的 100 万位,进行质因数分解等),任何 I/O-operation(加载文件,执行网络请求)或任何阻塞操作,因为这会占用 EDT 太久并阻止它处理 UI 事件。因此,这些任务应该 运行 在单独的线程上。但是由于不允许从 EDT 以外的其他线程更新 UI,因此您可以通过调用 SwingUtilities.invokeLater(updateTask).'hand-over' 向 EDT 执行 UI-update-task。 =13=]