SwingUtilities.invokeLater

Fad*_*lMS 52 java swing multithreading awt event-dispatch-thread

我的问题与此有关SwingUtilities.invokeLater.我应该什么时候使用它?每次需要更新GUI组件时是否必须使用?它到底是做什么的?是否有替代品,因为它听起来不直观,并添加看似不必要的代码?

aio*_*obe 52

每次需要更新GUI组件时是否必须使用?

不,如果您已经在事件派发线程(EDT)上,那么在响应用户发起的事件(例如点击和选择)时总是如此.(actionPerformed方法等,总是由EDT调用.)

如果您不在 EDT上并且想要进行GUI更新(如果您想从某个计时器线程或某些网络线程等更新GUI),则必须安排由EDT执行更新.这就是这种方法的用途.

Swing基本上是线程不安全的.即,与该API的所有交互都需要在单个线程(EDT)上执行.如果你需要从另一个线程(计时器线程,网络线程......)进行GUI更新,你需要使用你提到的方法(SwingUtilities.invokeLater,SwingUtilities.invokeAndWait,...).


mKo*_*bel 14

Swing is single threaded and all changes to the GUI must be done on EDT 
Run Code Online (Sandbox Code Playgroud)

基本用法 invokeLater()

  1. 应始终包含主要方法 invokeLater()

  2. 延迟(但异步)动作/事件到结束EventQueue,

  3. 如果EDT不存在则必须使用创建新的EDT invokeLater().你可以测试一下 if (SwingUtilities.isEventDispatchThread()) {...

  4. 存在invokeAndWait(),但直到今天我(只是我的看法)不能找个理由让使用 invokeAndWait()替代invokeLater(),除了硬变成GUI(JTree的&JTable的),但只是物质L&F(优秀的EDT事件的测试一致性)

  5. 基本的东西:Swing中的并发

  6. 必须包装后台任务的所有输出 invokeLater()


Amm*_*mar 7

每个Swing应用程序至少有2个线程:

  1. 执行应用程序的主线程
  2. EDT(事件调度线程)是一个更新UI的线程(因此UI不会冻结).

如果要更新UI,则应在EDT中执行代码.像SwingUtilities.invokeLater,SwingUtilities.invokeAndWait,EventQueue.invokeLater,EventQueue.invokeAndWait这样的方法允许您通过EDT执行代码.


Jér*_*nge 7

这次我的问题与SwingUtilities.invokeLater:我什么时候应该使用它?

要理解的关键是Java有一个单独的线程(EDT)来处理与Swing相关的事件.

您应该使用invokeLater()显示JFrame桌面应用程序的主要内容(例如),而不是尝试在当前线程中执行此操作.它还将创建上下文,以便稍后正常关闭应用程序.

这适用于大多数应用程序.

每次需要更新GUI组件时是否必须使用?它到底是做什么的?

否.如果您修改GUI组件,它将触发一个事件,该事件已注册以供Swing稍后调度.如果有此事件的监听器,EDT线程将在其后的某个地方调用它.您不需要使用invokeLater(),只需在组件上正确设置侦听器即可.

请记住,此线程与您的屏幕上绘制框架等相同.因此,侦听器不应执行复杂/长/ CPU密集型任务,否则屏幕将冻结.

是否有替代品,因为它听起来不直观,并添加看似不必要的代码?

您不需要编写更多代码,而不是使用invokeLater()您对组件感兴趣的+侦听器来显示您的应用程序.其余的由Swing处理.