所以我正在创建一个 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.");
}
}
My 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%。
由于在事件调度线程上异步通知 PropertyChangeListener,因此在调用任何 PropertyChangeListener 之前可能会发生对 setProgress 方法的多次调用。出于性能目的,所有这些调用都合并为一个仅具有最后一个调用参数的调用。
所以,毕竟,我的问题是:我做错了什么吗?如果没有,有没有办法让事件调度线程在 onProgress() 发生时或至少不时通知 PropertyChangeListeners?
观察:我正在测试的处理需要 3~5 秒。
守着星空守着你
相关分类