SwingWorker does not update JProgressBar without Thread.sleep() in custom dialog panel

会有一股神秘感。 提交于 2019-11-27 05:37:04
trashgod

The setProgress() API notes: "For performance purposes all these invocations are coalesced into one invocation with the last invocation argument only." Adding Thread.sleep(1) simply defers the coalescence; invoking println() introduces a comparable delay. Take heart that your file system is so fast; I would be reluctant to introduce an artificial delay. As a concrete example that illustrates the effect, I added intermediate reporting to this complete example, as shown below.

private static class LogWorker extends SwingWorker<TableModel, String> {
    private long fileLength;
    private long bytesRead;
    ...
    this.fileLength = file.length();
    ...
    while ((s = br.readLine()) != null) {
        publish(s);
        bytesRead += s.length();
        int progress = (int)(100 * bytesRead / fileLength);
        // System.out.println(progress);
        setProgress(progress);
    }
    ...
}

lw.addPropertyChangeListener((PropertyChangeEvent e) -> {
    if ("progress".equals(e.getPropertyName())) {
        jpb.setValue((Integer)e.getNewValue());
    }
    if ("state".equals(e.getPropertyName())) {
        SwingWorker.StateValue s = (SwingWorker.StateValue) e.getNewValue();
        if (s.equals(SwingWorker.StateValue.DONE)) {
            jpb.setValue(100);
        }
    }
});
Bence Kaulics

I wanted to track my SwingWorker's progress with a JProgressBar within a JDialog. However my SwingWorker class could not handle my custom DialogPanel class. To achieve the same result, using the default ProgressMonitor class was the best option.

I have passed the ProgressMonitor to the SwingWorker through its constructor:

private final File f;
private final ProgressMonitor pm

public FileLoadWorker(File f, ProgressMonitor pm)
{
    this.f = f;
    this.pm = pm;
}

and changed the following methods like this:

@Override
public void done() 
{
    try 
    {
        pm.setNote(get());
    } 
    catch (Exception e)
    {
        e.printStackTrace(System.err);
        System.out.println("error");
    }
}

@Override
protected void process(List<String> chunks)
{
   pm.setNote(chunks.get(chunks.size() - 1));
}

The task's propertyChangeListener changed like this:

final FileLoadWorker worker = new FileLoadWorker(f, pm);

worker.addPropertyChangeListener(new PropertyChangeListener()
{
    @Override
    public void propertyChange(final PropertyChangeEvent evt)
    {
        if("progress".equalsIgnoreCase(evt.getPropertyName())) 
        {
            pm.setProgress((int) evt.getNewValue());
        }

        if("state".equals(evt.getPropertyName())) 
        {
            SwingWorker.StateValue s = (SwingWorker.StateValue) evt.getNewValue();
            if(s.equals(SwingWorker.StateValue.DONE))
            {
                pm.setProgress(100);
                pm.close();
                Toolkit.getDefaultToolkit().beep();
            }
        }

        if(pm.isCanceled())
        {
            pm.close();
            worker.cancel(true);
        }
    }
});
worker.execute();

Thanks to trashgod for the answer and comments about the state property.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!