我似乎遇到了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());
}
}
亲切的问候
延
答案 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)
阅读SwingWorker,介绍了可能的方案,包括代码示例
setProgress(0);
和setProgress((int)((gotSize/(getSize))*100));
folows方法的输出可以在EDT during doInBackground()
上完成 process()
publish()
setProgress()
在发布SSCCE
答案 2 :(得分:0)
您可以尝试手动触发属性更改:
setProgress(1);
firePropertyChange("progress", 0, 1);