SwingWorker: свойство Change вызывается редко
Кажется, у меня проблема с SwingWorker. Я в основном реализовал пример кода Java, обновляющий пользовательский интерфейс из метода propertyChange() моего JFrame.
Я также скопировал сон до одной второй части в doInBackground. Это оставляет мне хорошую частоту обновления setProgress в моем Worker.
Однако событие 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());
}
}
С уважением
Jens
3 ответа
Ваша проблема вполне возможно здесь:
System.out.println("setProgress: "+(gotSize/getSize));
setProgress((int)((gotSize/(getSize))*100));
Вы проверяли, что прогресс на самом деле меняется? Лучше было бы напечатать:
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
}
читайте SwingWorker, там описаны возможные сценарии, включая примеры кода
setProgress(0);
а такжеsetProgress((int)((gotSize/(getSize))*100));
должен быть вызван на EDTвывод из следующих методов может быть сделан на EDT во время doInBackground()
process()
publish()
setProgress()
самый сложный пример кода от @trashgod о PropertyChangeListener
для лучшей помощи, скорее отправьте SSCCE
Вы можете попробовать запустить изменения свойств вручную:
setProgress(1);
firePropertyChange("progress", 0, 1);