0

Value is updated by the end, but not during the process. I guess the reason is that the publish method locates outside the loop.

As to invoke PropertyChangeListener, can it be achieved by defining the class without extends SwingWorker<Void, Void> ?

To address the question in another way, I have two threads locate in two different classes. Is it possible to build communication between the two using SwingWorker?

Class Application

import javax.swing.JFrame;

public class Application {
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new Progress();
                frame.setSize(200, 300);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });     
    }
}

Class Progress

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

@SuppressWarnings("serial")
public class Progress extends JFrame{
    private JProgressBar progressbar;

    public Progress(){
        JButton button = new JButton("Run");
        progressbar = new JProgressBar(0, 100);
        progressbar.setValue(0);
        progressbar.setStringPainted(true);
        JPanel panel = new JPanel();
        panel.add(button);
        panel.add(progressbar);
        add(panel, BorderLayout.PAGE_START);

        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                start();
            }
        });
    }

    private void start(){
        progressbar.setValue(0);

        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){

            @Override
            protected Void doInBackground() throws Exception {
                Simulation sim = new Simulation();
                publish(sim.getCount());
                return null;
        }

            @Override
            protected void process(List<Integer> chunks) {
                Integer progress = chunks.get(chunks.size()-1);
                progressbar.setValue(progress);
                progressbar.repaint();
                progressbar.update(progressbar.getGraphics());
            }

            @Override
            protected void done() {
                Toolkit.getDefaultToolkit().beep();
            }
        };
        worker.execute();
    }
}

Class Simulation

public class Simulation {
    private int count;

    public Simulation(){
        for(int i=0; i<100; i++){
            count++;
            System.out.println(count);

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public int getCount(){
        return count;
    }
}

How can I update the value during the process?

Milo Lu
  • 3,176
  • 3
  • 35
  • 46

1 Answers1

0

You need to implement PropertyChangeListener on your SwingWorker and listen to the Progress property changes and then from overridden propertChange() method update your JProgressBar.

Here is what you are looking.

Hope this helps.

Community
  • 1
  • 1
Sanjeev
  • 9,876
  • 2
  • 22
  • 33
  • I've read all those post. It's doesn't help. I have two threads locate in two classes. Question is how to communicate between the two using `SwingWorker` – Milo Lu May 16 '14 at 16:40
  • above code snippet only have one thread, you have to built upon the knowledges from links, you will not get whole code you need. – Sanjeev May 16 '14 at 16:46
  • Only one thread?? There are three threads involved in the life cycle of a SwingWorker: Current thread, Worker thread and EDT – Milo Lu May 16 '14 at 16:57
  • I know that, the only thing here is you have to take care of only one of these that is SwingWorker thread and align your code to use property change events – Sanjeev May 16 '14 at 17:02
  • That's what I am asking in the post!! You can't have SwingWorker in one class and PropertyChangeListener in another, right? There are two different threads! – Milo Lu May 16 '14 at 17:08
  • You can have them in two different classes what matters is that the calling of property changes happens within EDT and SwingWorker make it sure. – Sanjeev May 16 '14 at 17:13
  • You need to pass an instance of your main GUI to a controller, look at MVC. The idea is that you can send "requests" back to the controller which can then update your GUI. – Petro May 16 '14 at 17:16