How to update GUI from swingworker that returns two different values

I have a Java application that uses SwingWorker to update a shortcut and progress bar in a GUI, and it works well. However, I would like to add a function to this setting.

My swinging worker performs a task with length n and repeats this task m times. Right now, my GUI is just telling me how many times the task has been repeated, but I would like it to tell me also how long the task is. Say n=300 and m=50 , I would like something like:

 Task 49 is at 248 () Task has been repeated 48 times 

What should I change 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."); } } } 
+6
source share
1 answer

The second type of the V parameter in SwingWorker<T,V> used to perform intermediate results using these publishing methods and SwingWorker processes. It could be your own class. Here is an example based on a published SSCCE (short 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: Process Method Implementation Example

 @Override protected void process(List<Progress> progressList) { for (Progress p : progressList){ System.out.println(p.getTask() + " : " + p.getElement()); } } 

EDIT: UI Update Example

Here is a slightly modified version of the working implementation, similar to the example shown in the SwingWorker manual. The only changes are introducing the textArea member and updating the call to setProgress() in doInBackground() . The progress property is used to update the progress bar, process() used to update the 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(); } }); 
+7
source

Source: https://habr.com/ru/post/918105/


All Articles