防止GUI冻结,并有按钮取消操作/终止线程

这是我想要做的:

我有一个包含JTextAreaJFrame ,显示正在进行的连接的更新。 如果用户想要取消连接,则应该能够将JButton按到它的右侧。 但是,由于连接在尝试连接时阻塞(使用)线程,因此GUI将被冻结。 我正在寻找快速解决方案。 将ActionListener放在一个单独的线程上可能吗? 虽然我可以基本使用runnables,但我对线程没有多少经验。

答案是否与使用EDT有关? 如果是这样,应如何实施?

PS澄清一下,按钮应该可以杀死创建连接的线程。 看完后似乎是一个executorService。 可以帮忙吗? 是? 还是一点都不?

建议首先加快Swing(或几乎任何UI框架)和multithreading的速度。 这是餐巾纸版本:

  • 对UI的任何修改或从中读取(例如获取文本字段的值) 必须 在UI线程上进行(有时也称为“Swing Thread”或“Event Dispatch Thread”(EDT)
  • 任何阻塞或长时间运行的操作(如网络通信)都不能在UI线程上运行。 否则他们将阻止按钮工作,文本更新等。
  • 在Java中, ExecutorService及其朋友可以让在后台线程上运行长时间运行或阻塞内容相对容易
  • 如果需要更新UI的后台线程发生某些事情,请将与UI相关的代码封装在EventQueue.invokeLater调用中。 这将确保您传递的Runnable在UI线程上执行。

SwingWorker类封装了这个逻辑,并为更简单的案例提供了一个易于使用的帮助器。

当第一次这样做时,它可能有点令人生畏,但是要彻底理解这一点是值得的,因为它不仅适用于Swing,也适用于任何其他UI代码。

为了澄清,按钮应该能够杀死创建连接的线程。 看完后似乎是一个executorService。 可以帮忙吗? 是? 还是一点都不?

  • while(localBooleanVariable)Runnable#Thread ,plain Thread中

  • 通过使用SwingWorker.cancel()

  • 最简单的可能是SwingWorker ,因为可取消并且来自publish()progress()输出在EDT上