How to update a progress bar from a method inside

2019-07-25 07:56发布

问题:

I'm trying to update a progress bar and I can't do it. My code is something like this:

public class MyWorker extends SwingWorker<Void, Void> {

    public Void doInBackground(){
        howMany=Integer.parseInt(textField.getText());
        String result=longMethod(howMany);
        label.setText("Hello, you have "+result);
 }
}

        public class Event implements ActionListener{
    public void actionPerformed(ActionEvent e){
        label2.setText("Whatever");     
        button.setEnabled(false);
        myWorer.addPropertyChangeListener(this);
        myWorker.execute();
    }

    public void propertyChange(PropertyChangeEvent event){
        if("progress".equals(event.getPropertyName())){
           int currentPercent = (int)event.getNewValue();
            progressBar.setValue(currentPercent);
        }
    }
}

So I can't use setProgress in doInBackground since the updating is made by longMethod() which is the method containing a big slow loop, placed in another class. I've made something similar passing from that method a variable to the class which contains the JFrame and then offering the possibility to see that progress if you click another button.

I don't know if there is some way of making that button (or text field) refresh itself every X seconds without clicking it or a way to use the setProgress from the method longMethod()

Thank you!

回答1:

What you need is some way for longMethod to return progress information.

You could, for example, create a simple interface which you could pass to longMethod which would, when it knows, update the progress...

public interface ProgressMonitor {
    /**
     * Passes the progress of between 0-1
     */
    public void progressUpdated(double progress);
}

Then in your doInBackground method, you would pass an instance of the ProgressMonitor to the longMethod

public class MyWorker extends SwingWorker<Integer, Integer> {
    public Integer doInBackground(){
        // It would be better to have obtained this value before
        // doInBackground is called, but that's just me...
        howMany=Integer.parseInt(textField.getText());
        String result=longMethod(howMany, new ProgressMonitor() {
            public void progressUpdated(double progress) {
                setProgress((int)(progress * 100));
            }
        });
        //label.setText("Hello, you have "+result);
        publish(result);
        return result;
    }

    protected void process(List<Integer> chunks) {
        label.setText("Hello, you have "+chunks.get(chunks.size() - 1));
    }
}

This is esstenially an example of the observer pattern

Now, if you can't modify longMethod, then you have no means by which you can update the progress, because you have no way of knowing what the longMethod is doing...



回答2:

If there is a way to pass the Progress bar to the SwingWorker, then the SwingWorker would have a reference to that progress bar and be able to update it.