【发布时间】:2018-10-05 19:51:22
【问题描述】:
所以我创建了一个 JProgressBar 来显示 CSV 操作的进度,其中每一行都被读取并检查是否在强制性 (NOT NULL) 列中没有空值。为此,我创建了一个 SwingWorker 任务,它处理将文件中的行数转换为最大进度值的 100%,并以正确的速率累加进度。
这就是 SwingWorker:
public static class Task extends SwingWorker<String, Object> {
private int counter;
private double rate;
public Task(int max) {
// Adds the PropertyChangeListener to the ProgressBar
addPropertyChangeListener(
ViewHandler.getExportDialog().getProgressBar());
rate = (float)100/max;
setProgress(0);
counter = 0;
}
/** Increments the progress in 1 times the rate based on maximum */
public void step() {
counter++;
setProgress((int)Math.round(counter*rate));
}
@Override
public String doInBackground() throws IOException {
return null;
}
@Override
public void done() {
Toolkit.getDefaultToolkit().beep();
System.out.println("Progress done.");
}
}
我的PropertyChangeListener,由 JProgressBar 包装器实现:
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setIndeterminate(false);
progressBar.setValue((Integer) evt.getNewValue());
}
}
然后,在我实际使用它的地方,我用我需要的处理覆盖doInBackground() 方法,在每次迭代时调用step()。
Task read = new Task(lines) {
@Override
public String doInBackground() throws IOException {
while(content.hasNextValue()) {
step();
// Processing
}
return output.toString();
}
};
read.execute();
return read.get();
发生了什么:处理工作并成功,然后调用done(),然后propertyChange()注册两个“状态”事件和一个“进度”事件,设置ProgressBar 的进度从 0% 到 100%。
发生了什么 我认为发生了什么(check Hovercraft's answer 澄清)在 JavaDocs 中有描述:
因为在事件调度线程上异步通知 PropertyChangeListeners,所以在调用任何 PropertyChangeListeners 之前可能会发生对 setProgress 方法的多次调用。出于性能目的,所有这些调用仅与最后一个调用参数合并为一个调用。
那么,毕竟,我的问题是:我做错了什么吗?如果没有,我有没有办法让事件调度线程在 onProgress() 发生时通知 PropertyChangeListeners,或者至少不时通知?
Obs.:我正在测试的处理需要 3~5 秒。
【问题讨论】:
标签: java swing event-dispatch-thread jprogressbar propertychangelistener