简体   繁体   中英

Swing updating UI components while the job is running

I am developing a swing applciation. In that I have a workflow of jobs to be done.

I Am running these jobs in a for loop one after the other. The interesting thing is I have to update GUI status bar with the current job name running.

I can not use SwingUtilities.invokeAndWait as it can not run on the dispatch thread which will be the currently running thread.

I tried using SwingWorker since the jobs are running in a loop, the SwingWorker's doBackGrount() method will execute and will come out and gets the the next index to run the next job. In the done() of SwingWorker I have written code to update GUI with the status.

public class TestAction extends SwingWorker<Boolean, Void> {

    boolean executeThread = false;

    public TestAction() {
    }

    @Override
    protected Boolean doInBackground() throws Exception {
        executeThread = ExecuteWebServiceAction.webServiceExecution();
        return executeThread;
    }

    @Override
    protected void done() {
        try {
            boolean isOver = (boolean) get();
            if (isOver) {
                MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
                        + " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());
                FrameMain.jPanel6.repaint();
            }
        } catch (Interr`enter code here`uptedException ex) {
            Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ExecutionException ex) {
            Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

And this is where am calling TestAction:

if (!WorkFlow.isIsWorkflow()) {
    SwingUtilities.invokeLater(
      new Runnable() {
        @Override
        public void run() {
          webServiceExecution();
        }
    });
} else {
     new TestAction().execute();
}

running in a loop one after the other and notify UI when one is done

sounds like "big job with intermediate results". Intermediate results are supported via the publish/process methods:

  • implement doInBackground to loop through the jobs and call publish when one is terminated
  • implement process to do the ui update

you can use Thread.currentThread().sleep(5000); in SwingWorker's doInBackground method before currentthread finishes its execution and update your UI

You could add a Runnable to your constructor to be run when done() is over:

public class TestAction extends SwingWorker<Boolean, Void> {

    boolean executeThread = false;
    private final Runnable runWhenDone;

    public TestAction(Runnable runWhenDone) {
        this.runWhenDone = runWhenDone;
    }

    //...

    @Override
    protected void done() {
    try {
        boolean isOver = (boolean) get();
        if (isOver) {
            MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
                + " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());

            //Run the Runnable here
            runWhenDone.run();

            //...

And in your GUI class

Runnable r = new Runnable() {public void run() {updateTheTitle();}};
(new TestAction(r)).execute();
private void updateTheTitle() { yourTitle.setText("I am done");}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM