Java – swingworker is in the done method of another swingworker
First, I need to inform you that I'm trying to learn how to write code in Java It's a little difficult, but I believe I have it I have submitted some questions about swing workers in the past Each of them I thought I had it, but later I found that I was still learning I hope this time is not one of those times
Having said that, please tell me anything you think does not meet the standard, or may lead to problems in the future
Now ask questions!
I built a JFrame that loads something before it allows users to enter another page, press a button or anything else When the data is loaded, it unlocks the JFrame to allow the user to interact with the data
The problem is, (this is not a real problem, just a clarification) I need to perform another task, and users can interact with JFrame in this way. It will not disturb them and will update the results found by JFrame based on it An example might be version checking Notify the user according to whether the version has expired
Sample sudo code
protected void startJFrame() { JFrame myFrame = new JFrame();//Starts with disable/invisible components. Preventing the user from doing to much before allowed. SwingWorker<Void,Progress> loadingWorker = new SwingWorker<Void,Progress>() { @Override protected Void doInBackground() throws Exception { publish(new Progress(0,"Loading This")); // Set Percent loadingTasks.loadThis(); // Do Work!! publish(new Progress(25,"Loading That")); // Set Percent loadingTasks.loadThat(); // Do Work!! publish(new Progress(50,"Loading More")); // Set Percent loadingTasks.loadMore(); // Do Work!! publish(new Progress(75,"Loading Last")); // Set Percent loadingTasks.loadLast(); // Do Work!! publish(new Progress(100,"Loading Complete"));// Set Percent return null; } @Override protected void process(List<Progress> ProgressList) { for (Progress p : ProgressList) { System.out.println(p.getInt() + "% " + p.getString()); //Show user percent and what its doing. } } @Override protected void done() { try { get(); loadingTasks.WrapUp();//Set Variables or other small stuff. myFrame.userAllowed();//Lets the user interact with the whole JFrame. SwingWorker<Void,Void> secondWorker = new SwingWorker<Void,Void>() { @Override protected Void doInBackground() throws Exception { versionCheck.makeItSo();// Do Work!! return null; } @Override protected void done() { try { get(); versionCheck.wrapUp();//Set Variables or other small stuff. myFrame.showLabel();//Show a label with specific info. } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } }; secondWorker.execute(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } }; loadingWorker.execute(); }
The subject of this code
I worry about creating many objects instead of processing them just to pass multiple variables In particular, the progress object created in the first doinbackground method
Is this OK? Does it automatically process progress objects? If not, what will I do with them after I finish them?
Solution
Swingworker supports propertychange events, that is, you can listen when swingworker changes state or updates its progress... Yes, swingworker even supports progress notifications, such as
This means that you can set Property@R_301_951 @Ener to monitor changes in progress and status properties and take appropriate actions
Workers who simply set up progress updates
public class LoadMaster extends SwingWorker<Void,Progress> { @Override protected Void doInBackground() throws Exception { System.out.println("Working hard here,nothing to see..."); for (int index = 0; index < 100; index++) { Thread.sleep(10); setProgress(index); } return null; } @Override protected void done() { try { get(); } catch (Exception e) { } } }
An example Property@R_301_951 @ener …
public class LoadMasterPropertyChanegHandler implements Property@R_301_951@ener { private SwingWorkerExample example; public LoadMasterPropertyChanegHandler(SwingWorkerExample example) { this.example = example; } @Override public void propertyChange(PropertyChangeEvent evt) { System.out.println(evt.getPropertyName()); if ("progress".equalsIgnoreCase(evt.getPropertyName())) { int value = (int) evt.getNewValue(); example.showProgress(value); } else if ("state".equalsIgnoreCase(evt.getPropertyName())) { SwingWorker worker = (SwingWorker) evt.getSource(); if (worker.isDone()) { try { worker.get(); example.loadCompleted(); } catch (InterruptedException | ExecutionException exp) { example.loadFailed(); } } } } }
Now, all this is to send the information back to swingworkerexample (it's coming), so that you can determine what it should do
In this example, the loadcompleted method updates the UI and then starts the second worker
protected void loadCompleted() { //... LoadStuffWorker stuffWorker = new LoadStuffWorker(this); stuffWorker.execute(); }
In fact, I may use interfaces, so I won't expose this class publicly, but that's another day's topic
A complete example
import java.awt.EventQueue; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.beans.PropertyChangeEvent; import java.beans.Property@R_301_951@ener; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingWorker; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; public class SwingWorkerExample { private JProgressBar pb; private JPanel content; public static void main(String[] args) { new SwingWorkerExample(); } public SwingWorkerExample() { EventQueue.invokelater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | illegalaccessexception | UnsupportedLookAndFeelException ex) { } pb = new JProgressBar(); content = new JPanel(); content.setBorder(new EmptyBorder(10,10,10)); JFrame frame = new JFrame("Testing"); frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(content); frame.setLayout(new GridBagLayout()); frame.add(pb); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); LoadMaster master = new LoadMaster(); master.addProperty@R_301_951@ener(new LoadMasterPropertyChanegHandler(SwingWorkerExample.this)); master.execute(); } }); } protected void showProgress(int value) { pb.setValue(value); } protected void loadCompleted() { content.removeAll(); content.setLayout(new GridLayout(0,1)); content.add(new JLabel("All your base are belong to us")); content.revalidate(); LoadStuffWorker stuffWorker = new LoadStuffWorker(this); stuffWorker.execute(); } protected void loadFailed() { content.removeAll(); content.setLayout(new GridLayout(0,1)); content.add(new JLabel("Fail")); content.revalidate(); } protected void setVersion(String value) { content.add(new JLabel("Version: " + value)); content.revalidate(); } protected void Failed(String fail) { content.add(new JLabel(fail)); content.revalidate(); } public class LoadMaster extends SwingWorker<Void,Progress> { @Override protected Void doInBackground() throws Exception { System.out.println("Working hard here,nothing to see..."); for (int index = 0; index < 100; index++) { Thread.sleep(10); setProgress(index); } return null; } @Override protected void done() { try { get(); } catch (Exception e) { } } } public class LoadStuffWorker extends SwingWorker<String,Void> { private SwingWorkerExample example; public LoadStuffWorker(SwingWorkerExample example) { this.example = example; } @Override protected String doInBackground() throws Exception { System.out.println("Hanging about in the background"); Thread.sleep(3000); return "Hello from the dark side"; } @Override protected void done() { try { String value = get(); example.setVersion(value); } catch (InterruptedException | ExecutionException ex) { example.Failed("Fail while doing version check"); } } } public class Progress { } public class LoadMasterPropertyChanegHandler implements Property@R_301_951@ener { private SwingWorkerExample example; public LoadMasterPropertyChanegHandler(SwingWorkerExample example) { this.example = example; } @Override public void propertyChange(PropertyChangeEvent evt) { System.out.println(evt.getPropertyName()); if ("progress".equalsIgnoreCase(evt.getPropertyName())) { int value = (int) evt.getNewValue(); example.showProgress(value); } else if ("state".equalsIgnoreCase(evt.getPropertyName())) { SwingWorker worker = (SwingWorker) evt.getSource(); if (worker.isDone()) { try { worker.get(); example.loadCompleted(); } catch (InterruptedException | ExecutionException exp) { example.loadFailed(); } } } } } }