I have a Java app that uses a SwingWorker to update a label and a progress bar in the GUI and it works nice. However, I'd like to add a feature to this setting.
My swing worker performs a task which has length n
, and it repeats that task m
times. Right now my GUI just tells me how many time the task has been repeated, but I'd like it to tell me also at what length of the task we are in. Say n=300
and m=50
, I'd like something like:
Task 49 is at 248 ()
Task has been repeated 48 times
What should I modify in my SwingWorker?
/**
*
* @author digitaldust
*/
public class Model extends SwingWorker<Integer, Integer> {
private HashMap<String, Number> GUIparams;
private int session;
private int ticks;
Model(HashMap<String, Number> KSMParams) {
GUIparams = KSMParams;
session = (Integer)GUIparams.get("experimentsInSession");
ticks = (Integer)GUIparams.get("howManyTicks");
}
/**
* Actual simulation
*/
@Override
protected Integer doInBackground() throws Exception {
int i=0;
while(!isCancelled() && i<session){
i++;
int ii=0;
while(!isCancelled() && ii<ticks){
// this is n, the task length and I'd like to update the GUI with this value
ii++;
}
System.out.println(i);
// this is m, how many time the task has been repeated, and now it is updated in the GUI
publish(i);
setProgress(i);
Thread.sleep(1000);
}
return i;
}
/**
* Invoked when simulation exits
*/
@Override
protected void done() {
if (isCancelled()) {
Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session...");
} else {
// do stuff
Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended.");
}
}
}
The second type parameter V in SwingWorker<T,V>
is used for carrying out intermediate results by this SwingWorker's publish and process methods. This could be your custom class. Here is an example based on posted SSCCE (shortened for clarity):
class Progress {
private int task;
private int element;
public Progress(int task, int element) {
super();
this.task = task;
this.element = element;
}
...
}
public class Model extends SwingWorker<Integer, Progress> {
...
@Override
protected Integer doInBackground() throws Exception {
...
publish(new Progress(i, ii));
}
}
EDIT: example of process method implementation
@Override
protected void process(List<Progress> progressList) {
for (Progress p : progressList){
System.out.println(p.getTask() + " : " + p.getElement());
}
}
EDIT: example of UI update
Here is a slightly modified version of the worker implementation, similar to a sample demonstrated in SwingWorker manual. The only changes are introduction of textArea
member and updated setProgress()
call in doInBackground()
. progress
property is used to update the progress bar, process()
is used to update text area.
public static class Model extends SwingWorker<Integer, Progress> {
private HashMap<String, Number> GUIparams;
private int session;
private int ticks;
private JTextArea textArea;
Model(HashMap<String, Number> KSMParams, JTextArea textArea) {
GUIparams = KSMParams;
session = (Integer)GUIparams.get("experimentsInSession");
ticks = (Integer)GUIparams.get("howManyTicks");
this.textArea = textArea;
}
@Override
protected void process(List<Progress> progressList) {
for (Progress p : progressList){
textArea.append(p.getTask() + " : " + p.getElement() + "\n");
System.out.println(p.getTask() + " : " + p.getElement());
}
}
/**
* Actual simulation
*/
@Override
protected Integer doInBackground() throws Exception {
int i=0;
while(!isCancelled() && i<session){
i++;
int ii=0;
while(!isCancelled() && ii<ticks){
// this is n, the task length and I'd like to update the GUI with this value
ii++;
}
//System.out.println(i);
// this is m, how many time the task has been repeated, and now it is updated in the GUI
publish(new Progress(i, ii));
//setProgress(i);
setProgress(100 * i / session);
Thread.sleep(1000);
}
return i;
}
/**
* Invoked when simulation exits
*/
@Override
protected void done() {
if (isCancelled()) {
Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session...");
} else {
// do stuff
Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended.");
}
}
}
Here is a demo initialization:
final JProgressBar progressBar = new JProgressBar(0, 100);
final JTextArea textArea = new JTextArea();
final JButton button = new JButton("Start");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
HashMap<String, Number> map = Maps.newHashMap();
map.put("experimentsInSession", 10);
map.put("howManyTicks", 5);
Model task = new Model(map, textArea);
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
task.execute();
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With