简体   繁体   English

防止GUI冻结并具有取消操作/杀死线程的按钮

[英]prevent GUI from freezing and have button to cancel operation/kill thread

Here is what I am trying to do: 这是我正在尝试做的事情:

I have a JFrame containing a JTextArea displaying updates on an on going connection. 我有一个JFrame其中包含一个JTextArea显示正在进行的连接上的更新。 The user is supposed to be able to press the JButton to the right of it if they want to cancel the connection. 如果用户想要取消连接,则应该能够按下其右侧的JButton However, since the connection is blocking (using) the thread while trying to connect, the GUI becomes frozen. 但是,由于尝试进行连接时连接正在阻塞(使用)线程,因此GUI被冻结。 I am looking for a quick fix. 我正在寻找快速解决方案。 Having the ActionListener on a separate thread possibly? ActionListener放在单独的线程上可能吗? I do not have much experience with threads though I can make basic use of runnables. 尽管我可以基本使用可运行对象,但我对线程没有太多经验。

Does the answer have something to do with using the EDT? 答案是否与使用EDT有关? If so how should this be implemented? 如果是这样,应如何实施?

PS for clarification, the button should be able to kill a thread creating the connection. PS为澄清起见,该按钮应该能够杀死创建连接的线程。 After reading it seems that an executorService. 看完后似乎是executorService。 could help with this? 可以帮上忙吗? Yes? 是? or not at all? 还是根本不?

It would be advisable to first get up to speed regarding Swing (or virtually any UI framework) and multi-threading. 建议首先了解有关Swing(或几乎任何UI框架)和多线程的知识。 This is the napkin version: 这是餐巾纸的版本:

  • Any modifications to the UI or reads from it (eg to get the value of a textfield) must be done only on the UI thread (which is also sometimes called the "Swing Thread" or "Event Dispatch Thread" (EDT) 在UI的任何修改或从中读取(例如,以获得一个文本框的值) 必须在UI线程上只是做了(这有时也被称为“Swing线程”或“事件指派线程”(EDT)
  • Any blocking or long-running operations - like network communications - must NOT be run on the UI thread. 任何阻塞或长时间运行的操作(例如网络通信)都不得在UI线程上运行。 Otherwise they will prevent buttons from working, texts from being updated etc. 否则,它们将阻止按钮正常工作,文本无法更新等。
  • In Java, the ExecutorService and its friends will make it relatively easy to let long-running or blocking stuff run on a background thread 在Java中, ExecutorService及其朋友将使长期运行或阻塞的东西在后台线程上运行相对容易
  • If something happens on the background thread that requires you to update the UI, encapsulate the UI-related code in an EventQueue.invokeLater call. 如果在后台线程上发生需要您更新UI的事件,请将与UI相关的代码封装在EventQueue.invokeLater调用中。 This will make sure the Runnable you pass gets executed on the UI thread. 这将确保您传递的Runnable在UI线程上执行。

The SwingWorker class encapsulates this logic and provides an easy to use helper for simpler cases. SwingWorker类封装了此逻辑,并为更简单的情况提供了易于使用的帮助器。

When doing this the first time, it can be a bit daunting, but it pays off to understand this thoroughly, because it does not only apply to Swing, but to any other UI code, too. 第一次执行此操作时,可能会有些令人生畏,但彻底了解这一点很有意义,因为它不仅适用于Swing,而且适用于任何其他UI代码。

for clarification, the button should be able to kill a thread creating the connection. 为了澄清起见,该按钮应该能够杀死创建连接的线程。 After reading it seems that an executorService. 看完后似乎是executorService。 could help with this? 可以帮上忙吗? Yes? 是? or not at all? 还是根本不?

yes

  • while(localBooleanVariable) inside Runnable#Thread , plain Thread while(localBooleanVariable)Runnable#Thread内部,普通线程

  • by using SwingWorker.cancel() 通过使用SwingWorker.cancel()

  • easiest could be SwingWorker , because is cancelable and output from publish() , progress() is on EDT 最简单的可能是SwingWorker ,因为它是可取消的,并且从publish()输出, progress()在EDT上

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM