【问题标题】:Swing concurrency and Event-Dispatch ThreadSwing 并发和事件调度线程
【发布时间】:2015-04-01 13:48:20
【问题描述】:

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

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

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

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

            public void actionPerformed(ActionEvent e)
            {

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

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

【问题讨论】:

  • "..setting text in JText on.." 什么是JText?没关系.. 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。

标签: java multithreading swing event-dispatch-thread


【解决方案1】:

这比你想象的要简单得多。

当然,UI 元素的修改(例如设置标签文本、向按钮添加侦听器等)只能由事件调度线程 (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"));

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

【讨论】:

    猜你喜欢
    • 2014-08-11
    • 2015-11-06
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多