SwingUtilities.invokeLater

发布于 2024-12-01 14:24:30 字数 128 浏览 0 评论 0原文

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

My question is related to SwingUtilities.invokeLater. When should I use it? Do I have to use each time I need to update the GUI components? What does it exactly do? Is there an alternative to it since it doesn't sound intuitive and adds seemingly unnecessary code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

忱杏 2024-12-08 14:24:31

每次需要更新 GUI 组件时都必须使用吗?

不,如果您已经处于事件调度线程 (EDT) 上,情况总是如此,则不需要响应用户发起的事件(例如单击和选择)时。 (actionPerformed 方法等始终由 EDT 调用。)

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

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

Do I have to use each time I need to update the GUI components?

No, not if you're already on the event dispatch thread (EDT) which is always the case when responding to user initiated events such as clicks and selections. (The actionPerformed methods etc, are always called by the EDT.)

If you're not on the EDT however and want to do GUI updates (if you want to update the GUI from some timer thread, or from some network thread etc), you'll have to schedule the update to be performed by the EDT. That's what this method is for.

Swing is basically thread unsafe. I.e., all interaction with that API needs to be performed on a single thread (the EDT). If you need to do GUI updates from another thread (timer thread, networking thread, ...) you need to use methods such as the one you mentioned (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...).

高跟鞋的旋律 2024-12-08 14:24:31
Swing is single threaded and all changes to the GUI must be done on EDT 

invokeLater() 的基本用法

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

  2. 延迟(但异步)操作/事件到 EventQueue 的末尾,

  3. 如果 EDT 不存在,则必须使用 invokeLater() 创建一个新的 EDT。您可以使用 if (SwingUtilities.isEventDispatchThread()) {...

    进行测试。

  4. 您可以使用 if (SwingUtilities.isEventDispatchThread()) {...

    存在 invokeAndWait() ,但直到今天我(只是我的观点)可以找不到使用 invokeAndWait() 而不是 invokeLater() 的原因,除了对 GUI(JTree 和 JTable)进行硬更改,但只是使用Substance L&F(非常适合测试 EDT 上事件的一致性)

  5. 基本内容:Swing 中的并发

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

Swing is single threaded and all changes to the GUI must be done on EDT 

Basic usage for invokeLater()

  1. Main methods should be always wrapped in invokeLater()

  2. Delayed (but asynchronously) action/event to the end of EventQueue,

  3. If EDT doesn't exists then you have to create a new EDT by using invokeLater(). You can test it with if (SwingUtilities.isEventDispatchThread()) {...

  4. There exists invokeAndWait(), but till today I (just my view) can't find a reason for using invokeAndWait() instead of invokeLater(), except hard changes into GUI (JTree & JTable), but just with Substance L&F (excellent for testing consistency of events on the EDT)

  5. Basic stuff: Concurrency in Swing

  6. All output from background tasks must be wrapped in invokeLater()

习惯成性 2024-12-08 14:24:31

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

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

如果您想更新 UI,您应该在 EDT 中执行代码。
SwingUtilities.invokeLater、SwingUtilities.invokeAndWait、EventQueue.invokeLater、EventQueue.invokeAndWait 等方法允许您通过 EDT 执行代码。

Every Swing application has at least 2 threads:

  1. The main thread that executes the application
  2. The EDT (Event Dispatching Thread) is a thread that updates the UI (so the UI will not freeze).

If you want to update the UI you should execute code within the EDT.
Methods like SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait allow you to execute code by the EDT.

鲸落 2024-12-08 14:24:31

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

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

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

对于大多数应用程序来说就是这样。

每次需要更新 GUI 组件时都必须使用吗?它到底有什么作用?

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

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

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

除了在组件上使用 invokeLater() + 您感兴趣的侦听器显示应用程序之外,您不需要编写更多代码。其余的由 Swing 处理。

My question this time is related to SwingUtilities.invokeLater: When should I use it?

What is key to understand is that Java has a separate thread (EDT) handling Swing related events.

You should use invokeLater() to display the main JFrame of a desktop application (for example), instead of trying to do it in the current thread. It will also create the context for graceful closing of the application later.

That's about it for most applications.

Do I have to use each time I need to update the GUI components? What does it exactly do?

No. If you modify a GUI component, it will trigger an event which is registered for later dispatching by Swing. If there is a listener for this event, the EDT thread will call it somewhere down the road. You don't need to use invokeLater(), just set your listeners on components properly.

Keep in mind that this thread is the same thread drawing frames etc... on your screen. Hence, listeners should not perform complex/long/CPU intensive tasks, otherwise your screen will freeze.

Is there an alternative to it since it doesn't sound intuitive and adds seemingly unnecessary code?

You don't need to write more code than displaying your application with invokeLater() + listeners you are interested in on component. The rest is handled by Swing.

谎言 2024-12-08 14:24:31

大多数用户启动的事件(点击、键盘)已经在 EDT 上,因此您不必为此使用 SwingUtilities。这涵盖了很多情况,除了更新 EDT 的 main() 线程和工作线程。

Most user-initiated events (clicks, keyboard) will already be on the EDT so you won't have to use SwingUtilities for that. That covers a lot of cases, except for your main() thread and worker threads that update the EDT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文