Java eli5回转工和回转螺纹

Java eli5回转工和回转螺纹,java,swing,Java,Swing,我有一个程序,我从这里得到了一些帮助(),从那以后我一直在读关于swing worker的书。我仍然没有修复程序,因为我重读了3次官方文件,我仍然有点困惑。这是我认为我理解的,如果我错了,请纠正我 当您有一个很长的后台进程,并且您将SwingWorker放在您执行的操作中时,您使用SwingWorker?一旦创建了流程,如果希望它更新GUI,就可以让它返回一个值,然后从SwingWorker done()方法中获得()值。我对“在哪里”初始化SwingWorker感到困惑,因为我想说这是执行的操

我有一个程序,我从这里得到了一些帮助(),从那以后我一直在读关于swing worker的书。我仍然没有修复程序,因为我重读了3次官方文件,我仍然有点困惑。这是我认为我理解的,如果我错了,请纠正我

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


我觉得写出来很失落,我觉得我越来越接近理解了,但由于某种原因,它就是不起作用。我不喜欢官方文件提供的例子,我想我只是看不到整体情况。官方文件说要在SwingInvokeLater中初始化GUI,但我不明白这和在main()中初始化GUI有什么区别

您的问题/我的答复:

当您有一个很长的后台进程,并且您将SwingWorker放在您执行的操作中时,您使用SwingWorker

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

一旦创建了流程,如果希望它更新GUI,就可以让它返回一个值,然后从SwingWorker done()方法中获得()值

这是更新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()会更好吗

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

整个代码块是放在invokeLater中还是只放在更新GUI部分中。我觉得整个代码都应该放在invokeLater中,但有人告诉我只需更新GUI,例如invokeLater()中的(text.setText())

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


编辑2
你说:


我在测试时遇到的最后一个问题..在执行的一个操作中,我让按钮单击change textfield以说hi,然后我为Thread输入一个try catch。sleep(1000)然后将textfield更改为ho。为什么结果只有一个?它不显示hi,我用数字测试,可以看到程序锁定。我知道使用线程可以解决这一问题,但我只是想知道,如果我设置睡眠,为什么它不会显示输出


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

感谢您的回答,它帮助了您很多。所以我想我正朝着正确的方向前进。如果我有一个每小时在网站上检查一个值的进程,因为这是一个很短的进程(需要一秒钟),那么使用invokeLater()会更好吗?整个代码块是放在invokeLater中还是只放在更新GUI部分中。我觉得整个代码都应该放在invokeLater中,但有人告诉我只需更新GUI,比如invokeLater()中的(text.setText())。我在