1

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

我还在 doInBackground 中复制了最多一秒钟的睡眠部分。这使我的 Worker 中的 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());
        }
}

亲切的问候

延斯

4

3 回答 3

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);

现在检查 value 是否真的在变化。

哎呀,这绝对是错误的:

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

不要使用==. 请改用equals(...)orequalsIgnoreCase(...)方法。了解 == 检查两个对象是否相同,这不是您感兴趣的。另一方面,这些方法检查两个字符串是否具有相同顺序的相同字符,这在这里很重要。所以而不是

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

做,

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

或者,

if ("bar".equalsIgnoreCase(fu)) {
  // do something
}
于 2012-08-30T18:26:56.037 回答
2
  1. 阅读SwingWorker,描述了可能的场景,包括代码示例

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

  3. 在 doInBackground() 期间,可以在 EDT 上完成以下方法的输出

    • process()

    • publish()

    • setProgress()

  4. @trashgod 关于 PropertyChangeListener 的最复杂的代码示例

  5. 尽快发布SSCCE以获得更好的帮助

于 2012-08-30T18:28:56.963 回答
0

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

setProgress(1);
firePropertyChange("progress", 0, 1);
于 2015-11-18T08:05:00.973 回答