JFrame calls multiple concurrent threads that update the JProgressBar in the calling JFrame

Here's how it goes: I have a JFrame for the main window of a Java application that contains a panel with several JProgressBar. I want to start Thread for each JProgressBar, which will start other Threads on its own. When any of these "secondary" streams ends, I want to update the JProgressBar in my JFrame. Moreover, before ordering all this, since I do not want the user to be able to click anything on the JFrame, I also want to setEnabled (false) some buttons in the JFrame. Easy?

ActivarBotones abFalse = new ActivarBotones(false); abFalse.start(); try { abFalse.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } EstablecerConexiones ec = new EstablecerConexiones(); ec.start(); try { ec.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } ActivarBotones abTrue = new ActivarBotones(true); abTrue.start(); 

Two problems.

  • If I run the code from above, nothing is updated. If I just start the ec stream, everything works almost correctly.

  • I don’t know much about synchronization and I don’t know what to do to start all the “primary” threads at the same time.

Any clues?

+4
source share
2 answers

Here is a small example, I don’t think that it answers all your questions, but it demonstrates the basic concept (there is a sick wife and takes care of 6 months of age by typing one hand: P)

 public class ThreadedProgress { public static void main(String[] args) { new ThreadedProgress(); } public ThreadedProgress() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JPanel progressPane = new JPanel(new GridBagLayout()); JProgressBar progressBar = new JProgressBar(0, 100); progressPane.add(progressBar); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(progressPane); frame.setSize(200, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); new Thread(new MainThread(progressBar)).start(); } }); } public interface CallBack { public void done(Runnable runnable); } public static class MainThread implements CallBack, Runnable { public static final Object UPDATE_LOCK = new Object(); public static final Object WAIT_LOCK = new Object(); private List<Runnable> running = new ArrayList<>(25); private List<Runnable> completed = new ArrayList<>(25); private final JProgressBar progressBar; public MainThread(JProgressBar progressBar) { this.progressBar = progressBar; } @Override public void done(Runnable runnable) { synchronized (UPDATE_LOCK) { running.remove(runnable); completed.add(runnable); } int count = running.size() + completed.size(); updateProgress(completed.size(), count); synchronized (WAIT_LOCK) { WAIT_LOCK.notify(); } } protected void updateProgress(final int value, final int count) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { int progress = Math.round(((float) value / (float) count) * 100f); progressBar.setValue(progress); } }); } @Override public void run() { for (int index = 0; index < 5; index++) { ChildSpawn spawn = new ChildSpawn(this); running.add(spawn); } for (Runnable runnable : running) { new Thread(runnable).start(); } while (running.size() > 0) { synchronized (WAIT_LOCK) { try { WAIT_LOCK.wait(); } catch (InterruptedException ex) { } } } System.out.println("I'm all done"); } } public static class ChildSpawn implements Runnable { private CallBack callBack; public ChildSpawn(CallBack callBack) { this.callBack = callBack; } @Override public void run() { try { Thread.sleep((long)Math.round(Math.random() * 5000)); } catch (InterruptedException ex) { } callBack.done(this); } } } 
+2
source

ActivarBotones thread ActivarBotones not end.

If it works when you do not start this thread, then there is something in this thread that does not terminate. Otherwise, it will pass through the EstablecerConexiones stream. Since you call .join() on this thread after it starts, the code will not act until this thread is completed. So there must be something that blocks or gets into the loop.

Run the application in debug mode and place the breakpoint in the ActivarBotones stream. Track it and see why it does not end.

For your second problem, if you start each main thread, but do not join them until all are started, they will all be executed simultaneously. Of course, this greatly simplifies the situation. Many people prefer to use executing services to manage their flows. You also need to worry about a thread-safe implementation, so you don't run into synchronization issues. Finally, if you interact with Swing components, all of this must be done in a dedicated Dispatch thread.

+1
source

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


All Articles