问题
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.
来源:https://stackoverflow.com/questions/24945292/how-to-update-a-progress-bar-from-a-method-inside-swingworker