0

I'm starting to work with Java GUIs and I have some problems with SwingWorker: I'm trying to do a simple UI to start a server, run some "slave" objects and finally, run a master object managing all the work. I define the problem in the master (the number of tasks to do) and I have a progressBar in the UI that I want to update each time a task is done. I use a SwingWorker to update the progressBar, but I don't know how to do it right: in the background method it just sleeps until the master wakes it up when a task is done. Unfortunately it doesn't work and I would appreciate if someone could explain me what should I do.

I create the swingworker in the GUI and add a listener for update a progressBar:

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {

        worker = WorkerUpdater.getInstance();
        jProgressBar1.setValue(0);
        worker.addPropertyChangeListener(this);
        worker.execute();

This is the SwingWorker:

public class WorkerUpdater extends SwingWorker<Void, Integer> {

    private static WorkerUpdater instance;
    private int progress;
    private boolean changed = false;

    public int getProgreso(){
        return this.progress;
    }

    public void setProgreso(int p){
        this.progress = p;
        changed = true;
    }

    public static WorkerUpdater getInstance(){
        if(instance == null)
            instance = new WorkerUpdater();
        return instance;
    }

    @Override
    protected Void doInBackground() throws Exception {
        while(progress < 100){
            if(changed){
                setProgress(Math.min(progress, 100));
                changed = false;
            }
        }
        return null;
    }

}

And I want to update the value of the progress bar when a task is done in other class (client):

    public boolean taskIsDone(String taskID, Object[] retVal) throws RemoteException {

        System.out.println("Client: taskIsDone(): Old task: " + taskID);

        this.doneTasks++;
        this.progress = ((Double) Math.ceil(doneTasks / totalTasks)).intValue();

        synchronized (taskSynch) {
            worker.setProgress(progress);
            this.results.put(taskID, retVal);
            task_count--;
            taskSynch.notify();
        }

        System.out.println("Client: Task finished: " + taskID);

        return true;
    }

The problem is that the value of progress in the client class changes its value but the progress bar doesn't.

mreigosa
  • 1
  • 2
  • 4
    It would be helpful if you posted a SSCCE demonstrating what kind of trouble you are having. – ryvantage Mar 24 '14 at 16:47
  • The progress bar doesn't update by itself. You have to call `setValue` on it. I don't see you doing that except setting to 0. Also, your code is not thread-safe. In particular it's possible HotSpot is able to compile the `if(changed)` to `if(false)` because `changed` is not volatile. [HotSpot does similar optimizations.](http://stackoverflow.com/a/22241859/2891664) – Radiodef Mar 26 '14 at 15:45
  • I forgot to put the method, but I have one "propertyChange" and it's doesn't work. – mreigosa Mar 27 '14 at 16:18

0 Answers0