等待Swing完成更新JProgressBar,然后继续 [英] Wait for Swing to finish updating JProgressBar before continuing

查看:73
本文介绍了等待Swing完成更新JProgressBar,然后继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JFrame,它的布局管理器设置为CardLayout.其中有两个JPanel子类.一个是面板WordsLoadingPanel,其中显示文本正在加载单词..."并具有JProgressBar.另一个必须实际加载单词.这需要一段时间(100个单词大约需要10-14秒;这是一个非常有选择性的算法),因此我想向用户保证程序仍在运行.我使面板中的加载算法使用firePropertyChange(String, int, int)触发属性更改,并且WordsLoadingPanel可以很好地捕获更改-我知道这是因为我为此事件添加了一个侦听器以执行println,并且它可以正常工作.但是,当我将println更改为实际更改JProgressBar的值时,它什么也没做.我知道我正在正确更改值,因为如果我在算法开始之前设置值,则会在循环的最后一次迭代中起作用.我猜这是因为我的算法正在消耗计算能力,并且不允许JProgressBar更新.

I have a JFrame with a CardLayout set as its layout manager. This has two JPanel subclasses in it. One is a panel, WordsLoadingPanel, which displays the text "Loading words..." and has a JProgressBar. The other has to actually load the words. This takes a while (about 10-14 seconds for 100 words; it's a pretty selective algorithm), so I want to assure the user that the program is still working. I made the loading algorithm in the panel fire a property change with firePropertyChange(String, int, int), and the WordsLoadingPanel is catching the change just fine - I know this because I added a listener for this event to perform a println, and it works. However, when I change the println to actually changing the JProgressBar's value, it doesn't do anything. I know I'm changing the value right, because if I set the value before the algorithm starts, it works, and it works on the last iteration of the loop. I'm guessing this is because my algorithm is eating the computing power and won't let JProgressBar update.

所以,我的问题是:如何让我的算法等待Swing(这将是AWT Dispatching Thread?)在继续之前完成更新进度条吗?我尝试过:

So, my question is: How do I make my algorithm wait for Swing (would this be the AWT Dispatching Thread?) to finish updating the progress bar before continuing? I've tried:

    在循环的每次迭代中
  • Thread.yield
  • Thread.sleep(1000L)在循环的每次迭代中,尝试/捕获
  • 将所有内容放入SwingUtilities.invokeLater(Runnable)
  • 的循环中
  • 仅在SwingUtilities.invokeLater(Runnable)
  • 中放入CPU密集型算法
  • Thread.yield in each iteration of the loop
  • Thread.sleep(1000L) in each iteration of the loop, in a try/catch
  • putting everything in the loop in a SwingUtilities.invokeLater(Runnable)
  • putting only the CPU-intensive algorithm in a SwingUtilities.invokeLater(Runnable)

为进一步支持我的CPU进食算法假设(听起来像儿童故事……),当我将JProgressBar设置为不确定时,它只会在算法完成后开始移动

To further support my hypothesis of the CPU-eating algorithm (sounds like a children's story…), when I set the JProgressBar to indeterminate, it only starts moving after the algorithm finishes.

有人有什么建议吗?

谢谢!

推荐答案

要在后台执行昂贵的操作,请考虑使用

To do expensive operations in background, consider using the SwingWorker class. The documentation has examples on how to use it to do tasks that interact with the user interface in a separate thread, including progress display in JProgressBars.

如果您在理解类的工作方式时遇到困难,请考虑:

If you have trouble understanding how the class works, consider:

  • SwingWorker是具有两个参数的通用类:TV
  • doInBackground方法返回T,并在单独的线程中执行.
  • 由于只能在事件分发线程中操纵Swing,因此您不能在doInBackground中操纵Swing.
  • process方法将List<V>作为参数,并在事件调度线程上被异步调用.
  • publish方法采用V...参数,并将其发送给process方法进行处理.
  • SwingWorker is a generic class that takes two parameters: T, and V
  • The doInBackground method returns T and is executed in a separate thread.
  • Since Swing may only be manipulated in the Event Dispatch Thread, you may not manipulate Swing in doInBackground.
  • The process method takes a List<V> as a parameter and is called asynchronously on the Event Dispatch Thread.
  • The publish method takes V... arguments and sends them for processing in the process method.

结论:

  • T是计算结果的类型(如果有).
  • V是操作用户界面所需的数据类型.
  • 您的算法应完全在doInBackground中运行.
  • 用户界面应在process方法中进行操作.
  • 您的算法应使用publish将数据发送到process方法.
  • T is the type of the result of the computation, if any.
  • V is the type of the data needed to manipulate the user interface.
  • Your algorithm should run entirely in doInBackground.
  • The user interface should be manipulated in the process method.
  • Your algorithm should use publish to send data to the process method.

这篇关于等待Swing完成更新JProgressBar,然后继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆