我有一个程序,我从这里得到了一些帮助(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。
答案 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在睡眠完成之前无法执行任何更新。这正是您必须使用后台线程来执行此类操作的原因。