您的问题/我的回复:
当你有一个长的后台进程时你使用 SwingWorker,你把 SwingWorker 放在你执行的操作中?
它可以进入 ActionListener 内部,是的。您创建它并在需要的地方执行它,不多也不少。
一旦你创建了你的进程,如果你希望它更新 GUI,你让它返回一个值,然后你从 SwingWorker 的 done() 方法中 get() 值。
这是更新 GUI 的一种方法。您还可以使用发布/处理方法对来使用中间结果更新 GUI。您还可以使用附加到 SwingWorker 的 PropertyChangeListener 来更新 GUI。无论如何,在某个地方调用get() 通常是个好主意,即使没有返回任何内容,因为这将使您的 Swing GUI 能够意识到在 SwingWorker 运行期间可能引发的任何异常。
我很困惑“在哪里”初始化 SwingWorker,因为我想说它执行的操作,但这不就是 SwingInvokeLater 所涉及的地方吗?
SwingUtilities.invokeLater(...) 用于将代码排队到 Swing 事件线程,即 EDT。这在 ActionListener 内部不是必需的,因为它的代码已经在 Swing 事件线程上调用。
如果是这样的话,两者之间的区别是什么。
它们完全不同。同样,invokeLater(...) 用于调用事件线程上的代码,而 SwingWorker 用于从事件线程中调用长时间运行的代码。
我相信 SwingInvokeLater 和 done() 都通过在 EDT 上运行来更新您的 GUI。
是的,他们都可以。
官方文档说要在 SwingInvokeLater 中初始化你的 GUI,但我不明白这与在 main() 中初始化我的 GUI 之间的区别。
通过使用SwingUtilities.invokeLater(...),您可以保证传递给它的代码在 EDT(事件调度线程)上运行。如果你不这样做,你就没有这个保证。虽然许多 Swing 程序大部分时间都会在不这样做的情况下运行,但如果不注意这一点,它们可能(并且确实)有时会失败。
编辑
所以我想我正朝着正确的方向前进。如果我有一个在网站上每小时检查一个值的过程,因为它的过程很短(需要一秒钟),使用 invokeLater() 会更好吗?
您可以为此使用某种类型的计时器,可能是在 Swing 后台运行的 ScheduledExecutorService,也可能与 SwingWorker 一起运行。然后该进程将被称为 Swing 线程的后台,您可以通过发布/进程更新 GUI。
整个代码块是放在invokeLater 中还是只是更新GUI 部分。我觉得整个代码应该放在invokeLater中,但有人告诉我只是在invokeLater()中更新GUI,例如(text.setText())。
如前所述,您的 GUI 需要在 Runnable 内启动,该 Runnable 被传递到对 invokeLater(...) 的调用中。至于程序运行时,如果后台代码使用 SwingWorker 运行,则通常不需要调用 invokeLater(...)。这就是使用 SwingWorker 而不是普通的普通线程的原因之一。
编辑 2
你说:
我刚刚在测试时遇到的最后一个问题..在执行的操作中,我让 buttonclick 更改文本字段以打招呼,然后我为 Thread.sleep(1000) 设置了 try catch,然后将文本字段更改为打招呼。为什么结果只输出 ho?它不显示嗨,我用数字测试过,可以看到程序锁定。我知道使用线程可以解决这个问题,但只是想知道为什么如果我休眠它不会显示输出。
当您调用 Thread.sleep(...) 时,您将调用线程(此处为 Swing 事件调度线程或 EDT)休眠。由于它负责所有 Swing 绘制和用户交互,因此整个应用程序进入休眠状态,并且 GUI 在休眠完成之前无法执行任何更新。这正是您必须使用后台线程来执行此类事情的原因。