eli5摆动工人和摆动螺纹

时间:2013-11-28 17:47:44

标签: java swing

我有一个程序,我从这里得到了一些帮助(how do I make my program check the stock market value every hour[java]),从那时起我一直在阅读有关摇摆工作者的文章。我仍然没有修复程序,因为我重读官方文档3次,我仍然有点困惑。以下是我认为我理解的内容,如果我错了,请纠正我。

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

我感到很遗憾只是写下这一切,我觉得我越来越接近理解,但由于某种原因它只是不会点击。我不喜欢官方文件提供的例子,我想我只是看不到全貌。官方文档说要在SwingInvokeLater中初始化你的GUI,但我不明白它之间的区别,只是在main()中初始化我的GUI。

1 个答案:

答案 0 :(得分:2)

您的问题/我的回复:

  

如果您有很长的后台进程,并且将SwingWorker放在执行的操作中,您可以使用SwingWorker吗?

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

  

如果您希望它更新GUI,那么一旦创建了流程,您就会返回一个值,并从SwingWorker done()方法获取()值。

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

  

我很困惑“在哪里”初始化SwingWorker,因为我想说它执行的动作,但不是涉及SwingInvokeLater的地方?

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

  

如果是这种情况,那么两者之间的区别是什么。

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

  

我相信SwingInvokeLater和done()都会通过在EDT上运行来更新你的GUI。

是的,他们都可以。

  

官方文档说要在SwingInvokeLater中初始化你的GUI,但我不明白它之间的区别,只是在main()中初始化我的GUI。

通过使用SwingUtilities.invokeLater(...),您可以保证传递给它的代码在EDT上运行,即Event Dispatch Thread。如果你不这样做,你没有这个保证。虽然许多Swing程序大部分时间都没有运行,但如果不采取这种措施,它们有时会(并且确实会)失败。


修改

  

所以我想我正朝着正确的方向前进。如果我有一个在网站上每小时检查一次值的进程,由于它的进程很短(需要一秒钟),使用invokeLater()会更好吗?

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

  

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

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


编辑2
你说:

  

我刚刚在测试时遇到的最后一个问题。在执行的操作中,我按下了buttonclick更改文本字段,然后我为Thread.sleep(1000)添加了一个try catch,然后将text更改为ho。为什么结果只输出ho?它没有显示嗨,我测试了数字,可以看到程序锁定。我知道使用一个线程会解决这个问题,但只是想知道为什么如果我睡觉就不会显示输出。

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