防止GUI冻结,并有按钮取消操作/终止线程
这是我想要做的:
我有一个包含JTextArea
的JFrame
,显示正在进行的连接的更新。 如果用户想要取消连接,则应该能够将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上