我读过许多有关JProgressBar的文章……包括在Java上发现的狡猾代码; here.
大多数表明您需要一个SwingWorker来使事情正确进行,这非常有意义,我非常了解。我发现当我调用setProgress(value)来更新进度条时,大多数情况下都不会触发propertyChange事件。我已经检查了我传递给setProgess的值,它肯定每次都会更改,因此我不确定它是否只是在太快触发事件?请参阅下面的相关代码,我们将不胜感激任何帮助/解释。
class ProgBar extends SwingWorker
{
public ProgBar()
{
addPropertyChangeListener(new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if ("progress".equals(evt.getPropertyName()))
{
int value = (Integer)evt.getNewValue();
System.out.println("propertyChange called with: " + value);
loginProg.setValue(value);
}
}
});
loginProg.setStringPainted(true);
loginProg.setValue(0);
setProgress(0);
}
@Override
public Void doInBackground() throws InterruptedException
{
...
int count = 0;
for (Folder f : folders)
{
... // process 'f'
setProgress((int)Math.min(((double)count/folders.length)*100.0, 100.0));
}
...
return null;
}
@Override
public void done()
{
System.out.println("Done called.");
setProgress(100);
loginProg.setValue(100);
}
}
JProgressBar以此调用;
private void jButtonActionPerformed(java.awt.event.ActionEvent evt)
{
// Create new thread to run progess bar.
// Otherwise won't be able to update progress bar.
ProgBar pb = new ProgBar();
pb.execute();
}
}
编辑:
是的,所以我应该更好地阅读Javadocs。
由于PropertyChangeListener是在事件调度线程上异步通知的,因此在调用任何PropertyChangeListener之前,可能会对setProgress方法进行多次调用。为了提高性能,所有这些调用仅与最后一个调用参数合并为一个调用。
例如,以下调用:
setProgress(1);
setProgress(2);
setProgress(3);
可能会导致单个PropertyChangeListener通知的值为3。
即我认为setProgress触发得太快是正确的。 ProgressMonitor可能是更好的解决方案。
最佳答案
这不是答案,而是演示sscce,向您展示我的意思:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Random;
import javax.swing.*;
public class TestProgBar {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ProgBar progBar = new ProgBar();
// **** this is key and where your code may be deficient ***
JProgressBar prog = progBar.getProg();
progBar.execute();
JOptionPane.showMessageDialog(null, prog);
}
});
}
}
class ProgBar extends SwingWorker<Void, Void> {
private JProgressBar loginProg = new JProgressBar();
public ProgBar() {
addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int value = (Integer) evt.getNewValue();
System.out.println("propertyChange called with: " + value);
loginProg.setValue(value);
}
}
});
loginProg.setStringPainted(true);
loginProg.setValue(0);
setProgress(0);
}
public JProgressBar getProg() {
return loginProg;
}
@Override
public Void doInBackground() throws InterruptedException {
int count = 0;
int max = 5;
Random random = new Random();
// simulate uploading files
while (count < 100) {
count += random.nextInt(max);
if (count > 100) {
count = 100;
}
setProgress(count);
Thread.sleep(400);
}
// for (Folder f : folders) {
// setProgress((int) Math.min(((double) count / folders.length) * 100.0,
// 100.0));
// }
return null;
}
@Override
public void done() {
System.out.println("Done called.");
setProgress(100);
loginProg.setValue(100);
}
}
再次,此代码可以正常工作,表明您已加载的代码未显示错误。您需要做进一步的工作来隔离错误并将其放入代码中,以便我们进行测试。