Update JProgressBar during processing

I know that the subject has already been seen in many Questions and an answer has been given, but still I cannot miss it.

I just want to update the progressBar by extracting some things from a large xml file. I thought that this was enough to have a long cycle in another thread, but? .. All I managed to get was progress, which either was not shown at all or was updated at the end, shortly before its closure.

Once close to launching an application, I:

public class SomeClass { private SomeClass () { myXMLParser reader = new myXMLParser(); CoolStuff fromXml = reader.readTheXml(); } } 

when showing and updating JDialog using JProgressBar:

 public class LoadingDialog extends JDialog { private JProgressBar progressBar; /* ... */ public void progress() { progressBar.setValue(progressBar.getValue() + 1); } } 

So, I have this myXMLParser:

 public class myXMLParser { private LoadingDialog loadingDialog = new LoadingDialog(); public CoolStuff readTheXml() { CoolStuff fromXml = new CoolStuff(); while(manyIterations) { loadingDialog.progress(); fromXml.add(some() + xml() + reading()); } return fromXml; } } 

I saw a lot of things with SwingWorker and using PropertyChange events updating the progressBar, but examples are always given all-in-one with processing and progress bar within the same class and with classes inside the classes, and since I start in Java, I could not translate this into your situation.

Any help? .. Any (not too obvious) tips?

Edit: Thus, thanks to btantlinger, it worked as follows:

 public class SomeClass { private SomeClass () { myXMLParser reader = new myXMLParser(); new Thread(new Runnable() { @Override public void run() { CoolStuff fromXml = reader.readTheXml(); } }).start(); } } public class LoadingDialog extends JDialog { private JProgressBar progressBar; /* ... */ public void progress() { progressBar.setValue(progressBar.getValue() + 1); } } public class myXMLParser { private LoadingDialog loadingDialog = new LoadingDialog(); public CoolStuff readTheXml() { CoolStuff fromXml = new CoolStuff(); while(manyIterations) { SwingUtilities.invokeLater(new Runnable() { public void run() { loadingDialog.progress(); } }); fromXml.add(some() + xml() + reading()); } return fromXml; } } 
+4
source share
2 answers

You MUST update the JProgress panel in the Swing event dispatch thread. You cannot modify Swing components in any other thread.

The only alternative would be to set the "undefined" JProgress panel before you start your thread, when the progress bar will just go back and forth.

eg

 progBar.setIndeterminate(true); 

See javadoc SwingWorker: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

If you do not want to use SwingWorker, another option is the SwingUtilities.invokeLater method

 //inside your long running thread when you want to update a Swing component SwingUtilities.invokeLater(new Runnable() { public void run() { //This will be called on the EDT progressBar.setValue(progressBar.getValue() + 1); } }); 
+10
source

In addition to the code provided by @btantlinger, after testing, I found that he needed an extra line of code to update the progress bar in the user interface thread during processing. See below.

  SwingUtilities.invokeLater(new Runnable() { public void run() { progressBar.setValue((int)percentage); //below code to update progress bar while running on thread progressBar.update(progressBar.getGraphics());} }); 
0
source

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


All Articles