2013-04-29 71 views
0

这里就是我想要做:防止GUI冻结,并有键取消操作/杀死线程

我有一个包含在一个持续连接的JTextArea显示更新一JFrame。如果用户想要取消连接,则应该能够按JButton。但是,由于连接在尝试连接时阻塞(使用)线程,因此GUI变为冻结状态。我正在寻找一个快速修复。可能在单独的线程上有ActionListener?尽管我可以基本使用runnables,但我对线程没有太多经验。

答案与使用EDT有关吗?如果是的话,这应该如何实施?

PS为了澄清,该按钮应该能够杀死创建连接的线程。看完后,似乎是一个executorService。可以帮助这个?是?或根本没有?

+0

所以你不能在连接上使用超时参数? – 2013-04-29 10:59:21

+0

这实际上是在建立连接并且设备使用文本协议进行通信之后。我希望能够取消尝试,如果其他设备不响应​​,即我会卡住尝试从网络读取流。 – 2013-04-29 11:17:19

回答

4

建议首先了解有关Swing(或者几乎所有的UI框架)和多线程的速度。这是餐巾纸版本:

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

SwingWorker类封装了这个逻辑,为简单的情况提供了一个简单易用的帮助器。

第一次这样做的时候,它可能有点令人生畏,但它可以彻底地理解它,因为它不仅适用于Swing,还适用于其他任何UI代码。

1

为了澄清,按钮应该能够杀死创建连接的线程。看完后,似乎是一个executorService。可以帮助这个?是?或根本没有?通过使用SwingWorker.cancel()

    • while(localBooleanVariable)Runnable#Thread,普通螺纹

    • 最简单的可能是SwingWorker,因为是取消和publish()输出,progress()是EDT