SwingWorker:很少调用propertyChange

时间:2012-08-30 18:10:47

标签: java performance swing swingworker propertychangelistener

我似乎遇到了SwingWorker的问题。 我基本上实现了Java示例代码,从我的JFrame的propertyChange()方法更新UI。

我还在doInBackground中将睡眠复制到一秒钟。 这让我在我的工作者中获得了很好的setProgress更新率。

但是,propertyChange事件大约每10秒触发一次。 我从API中了解到并非每个setProgress都会触发一个事件,而且我对此感到满意,但是看起来这有点慢,太多事件都会丢失。

当在调试器中单步执行时,我获得了更好的速率,〜每3次调用setProgress

任何想法为什么这么慢?

以下是我的代码部分:

public Void doInBackground() {
    Random random = new Random();
    setProgress(0);
    float getSize=0,gotSize=0;
    while (Sync.syncing) {
        //Sleep for up to one second.
        try {
             Thread.sleep(random.nextInt(1000));
        } catch (InterruptedException ignore) {
            ignore.printStackTrace();
        }
        try{
            getSize=Main.getSyncGet();
            gotSize=Main.getSyncGot();
            System.out.println("setProgress: "+(gotSize/getSize));
            setProgress((int)((gotSize/(getSize))*100));
        }catch(Exception e){
            Main.LOGGER.log(Level.WARNING,"Error setting progress",e);
        }
    }
    return null;
}

public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" == evt.getPropertyName()) {
            jpb.setValue((Integer) evt.getNewValue());
        }
}

亲切的问候

3 个答案:

答案 0 :(得分:4)

你的问题很可能在这里:

System.out.println("setProgress: "+(gotSize/getSize));
setProgress((int)((gotSize/(getSize))*100));

您是否测试过进度实际上是否已被更改?一个更好的println将是:

int value = (int)((gotSize/(getSize))*100);
System.out.println("setProgress: "+ value);
setProgress(value);

现在检查价值是否实际上正在改变。

哎呀,这绝对是错误的:

public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" == evt.getPropertyName()) {
            jpb.setValue((Integer) evt.getNewValue());
        }
}

不要使用==来比较字符串。请改用equals(...)equalsIgnoreCase(...)方法。理解==检查两个对象是否相同,而不是您感兴趣的。另一方面,这些方法检查两个字符串是否具有相同顺序的相同字符,这才是最重要的。而不是

if (fu == "bar") {
  // do something
}

做,

if ("bar".equals(fu)) {
  // do something
}

,或者

if ("bar".equalsIgnoreCase(fu)) {
  // do something
}

答案 1 :(得分:2)

  1. 阅读SwingWorker,介绍了可能的方案,包括代码示例

  2. 必须在EDT上调用
  3. setProgress(0);setProgress((int)((gotSize/(getSize))*100));

  4. folows方法的输出可以在EDT during doInBackground()

    上完成
    • process()

    • publish()

    • setProgress()

  5. 最复杂的code example by @trashgod about PropertyChangeListener

  6. 在发布SSCCE

  7. 后尽早获得更好的帮助

答案 2 :(得分:0)

您可以尝试手动触发属性更改:

setProgress(1);
firePropertyChange("progress", 0, 1);