繁体   English   中英

等待Swing完成JProgressBar的更新,然后继续

[英]Wait for Swing to finish updating JProgressBar before continuing

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

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

  • Thread.yield的每次迭代中的Thread.yield
  • 在try / catch中,每次循环迭代中的Thread.sleep(1000L)
  • 将所有内容放入SwingUtilities.invokeLater(Runnable)中的循环中
  • 仅将CPU密集型算法放入SwingUtilities.invokeLater(Runnable)

编辑:为了进一步支持我的CPU为食算法的假设(听起来像一个孩子的故事...),当我设置JProgressBar不确定的,它只启动算法完成移动。

有没有人有什么建议?

谢谢!

要在后台执行昂贵的操作,请考虑使用SwingWorker类。 该文档提供了有关如何使用它来执行与用户界面在单独线程中进行交互的任务的示例,包括JProgressBar的进度显示。

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

  • SwingWorker是具有两个参数的通用类: TV
  • doInBackground方法返回T并在单独的线程中执行。
  • 由于只能在事件doInBackground线程中操纵Swing,因此您不能在doInBackground操纵Swing。
  • process方法将List<V>作为参数,并在事件调度线程上被异步调用。
  • publish方法采用V...参数,并将其发送以在process方法中进行处理。

结论:

  • T是计算结果的类型(如果有)。
  • V是操作用户界面所需的数据类型。
  • 您的算法应完全在doInBackground运行。
  • 用户界面应在process方法中进行操作。
  • 您的算法应使用publish将数据发送到process方法。

好的,我已经解决了。 对于可能遇到类似问题的任何人,我的解决方案是将启动算法的方法从同步执行改为异步执行(使用new Thread(Runnable).start )。 所以,我的代码现在

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        new Thread(new Runnable () {
            public void run () {
                window.keyboardTrainingPanel.initialize();                                  
            }
        }).start();
    }
});

我希望这可以帮助别人! 但是,如果有更好的方法可以执行此操作,请随时通知我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM