Java Swing Threading with Updatable JProgressBar

淺唱寂寞╮ 提交于 2019-12-02 00:02:07

No need to call the frame inside invokeAndWait but you should update progress bar state like this.

try {
   SwingUtilities.invokeAndWait( new Runnable() {
     public void run() {
//update state of the progress bar here
     }
   });
 } catch (InterruptedException e) {
 } catch (InvocationTargetException e) { }

For running a series of operations in the background and reporting progress, use SwingWorker.

The background method does the background processing.
Use the publish method to post periodic status updates.
Override the process method to handle the updates (process always executes on the EDT).

progressBar = new JProgressBar();
sw = new SwingWorker<Boolean,Integer>() {
    protected Boolean doInBackground() throws Exception {
        // If any of the operations fail, return false to notify done() 
        // Do thing 1
        publish(25);  // 25% done
        // Do thing 2
        publish(50);  // 50% done
        // Do thing 3
        publish(75);  // 75% done
        // Do thing 4
        return true;
    }
    protected void process(List<Integer> chunks) {
        for (Integer i : chunks)
            progressBar.setValue(i);
    }
    protected void done() {
        try {
            boolean b = get();
            if (b)
                progressBar.setValue(100); // 100% done
            else
                // Notify the user processing failed
        }
        catch (InterruptedException ex) {
                // Notify the user processing was interrupted
        }
        catch (ExecutionException ex) {
                // Notify the user processing raised an exception
        }
    }
};

Addendum:

This can be extended to multiple tasks, it just requires changing how you approach setting the progress bar. Here's what comes to mind:

Have an array of completion counter, one per task.

int[] completions = new int[numTasks];
Arrays.fill(completions,0);

Start the SwingWorkers, each passed an index number. The process or done methods then call something like this to update the overall progress bar.

void update(int index, int percComplete) {
    completions[index] = percComplete;
    int total = 0;
    for(int comp: completions)
        total += comp/numTasks;
    overallPB.setValue(total);
}

Optionally, display a JProgressBar per task.

Addendum 2:

If the tasks vary in completion time (eg, cache hit vs cache miss), you may want to investigate ProgressMonitor. It's a progress dialog that only appears if the task takes more than some (configurable, default 500ms) amount of time.

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