java - eli5 Swing 工作器和 Swing 线程

标签 java swing

我有一个程序,我从这里得到了一些帮助(how do I make my program check the stock market value every hour[java]),从那以后我一直在阅读有关 Swing worker 的文章。我仍然没有修复该程序,因为我重读了官方文档 3 遍,但我仍然有点困惑。以上是我的理解,如有错误请指正。

当你有一个很长的后台进程时,你使用SwingWorker,并且你把SwingWorker放在你执行的操作中?创建流程后,如果您希望它更新 GUI,您可以让它返回一个值,然后从 SwingWorker did() 方法中 get() 该值。我对初始化 SwingWorker 的“位置”感到困惑,因为我想说它执行的操作,但这不是涉及 SwingInvokeLater 的地方吗?如果是这样的话,那么两者之间有什么区别。我相信 SwingInvokeLater 和 done() 都通过在 EDT 上运行来更新您的 GUI。

只是把这些全部写出来,我就感到迷失了,我觉得我越来越接近理解,但由于某种原因,它就是不会点击。我不喜欢官方文档提供的示例,我想我只是没有看到全貌。官方文档说要在 SwingInvokeLater 中初始化 GUI,但我不明白这与在 main() 中初始化 GUI 之间的区别。

最佳答案

您的问题/我的回复:

You use SwingWorker when you have a long background process, and you put the SwingWorker inside your action performed?

它可以进入 ActionListener 内部,是的。您创建它并在需要的地方执行它,不多也不少。

Once you create your process if you want it to update the GUI you make it return a value and you get() the value from the SwingWorker done() method.

这是更新 GUI 的一种方法。您还可以使用发布/处理方法对来使用临时结果更新 GUI。您还可以使用附加到 SwingWorker 的 PropertyChangeListener 来更新 GUI。无论如何,调用 get() 通常是个好主意。某处,即使没有返回任何内容,因为这将允许您的 Swing GUI 知道在 SwingWorker 运行期间可能抛出的任何异常。

I am confused "where" to initialize SwingWorker because I want to say its the action performed, but isn't that where SwingInvokeLater is involved?

SwingUtilities.invokeLater(...)用于将代码排队到 Swing 事件线程(EDT)上。这在 ActionListener 内部不是必需的,因为它的代码已在 Swing 事件线程上调用。

if that is the case than what is the difference between the two.

他们是完全不同的。再次,invokeLater(...)是在事件线程上调用代码,SwingWorker 用于从事件线程调用长时间运行的代码。

I believe SwingInvokeLater and done() both update your GUI by being run on the EDT.

是的,他们都可以。

The official doc said to initialize your GUI inside a SwingInvokeLater but I don't understand the difference between that and just initializing my GUI in main().

通过使用 SwingUtilities.invokeLater(...)您保证传递给它的代码在 EDT(事件调度线程)上运行。如果你不这样做,你就没有这个保证。虽然许多 Swing 程序在大多数情况下都会运行而不这样做,但如果不采取这种措施,它们有时可能(并且确实)会失败。

<小时/>

编辑

So I guess I am heading in the right direction. If I have a process that checks a value every hour on a website, since its a short process(takes a second) will it be better to use invokeLater()?

为此,您可以使用某种类型的计时器,可能是 ScheduledExecutorService,它可能在 Swing 后台运行,也可能与 SwingWorker 一起运行。然后该进程将被称为 Swing 线程的后台,您可以通过发布/进程更新 GUI。

Does the entire block of code go inside invokeLater or just the updating the GUI part. I feel like the entire code should go inside invokeLater but someone told me just to update the GUI such as (text.setText()) inside invokeLater().

如上所述,您的 GUI 需要在传递给 invokeLater(...) 的调用的 Runnable 内部启动。 。至于程序运行时,如果后台代码使用 SwingWorker 运行,那么通常不需要调用 invokeLater(...) 。这是使用 SwingWorker 而不是普通线程的原因之一。

<小时/>

编辑2
您声明:

one last question I just came across while testing..inside an action performed I made the buttonclick change textfield to say hi, then I put in a try catch for Thread.sleep(1000) then change textfield to say ho. How come the result only outputs ho? it doesnt show hi, I tested with numbers and can see the program locking up. I know using a thread will fix this but just wondering why it wont display the output if I put a sleep.

当您调用Thread.sleep(...)时您将调用线程(此处为 Swing 事件调度线程或 EDT)置于 sleep 状态。由于它负责所有 Swing 绘制和用户交互,因此整个应用程序将进入休眠状态,并且 GUI 在 sleep 完成之前无法执行任何更新。这正是您必须使用后台线程来执行此类操作的原因。

关于java - eli5 Swing 工作器和 Swing 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20272120/

相关文章:

java - Applet param 标签有什么用?

java - 结合 Java Swing 和 Java3D : performance problems with concurrency

java - Repaint() 重新定位按钮

java swing根据jLabel调整ImageIcon的大小

java - 当尝试使用 react 数据时,我得到了 bean 类 [reactor.core.publisher.MonoOnAssembly] 的无效属性 'id'

java - 将 .lnk 文件拖到 Windows 10 任务栏

java - 从 MyListener 类访问 MyPanel 类按钮

Java 图标文件不显示图像

java - 如何将参数从表单发送到 Servlet(出生日期)(选择日、月、年、选项)Java

java - JFileChooser 中的 UIManager 颜色