Reputation: 527
Here is my example code:
package javaapplication35;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import static javaapplication35.ProgressBarExample.customProgressBar;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
public class ProgressBarExample {
final static JButton myButton =new JButton("Start");
final static JProgressBar customProgressBar = new JProgressBar();
private static final JPanel myPanel = new JPanel();
public static void main(String[] args) {
customProgressBar.setMaximum(32);
customProgressBar.setStringPainted(true);
myPanel.add(customProgressBar);
myPanel.add(myButton);
myButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
Thread firstly =new Thread(new Runnable (
) {
@Override
public void run() {
Calculations a = new Calculations();
a.doCaculations();
}
});
Thread secondly =new Thread(new Runnable (
) {
@Override
public void run() {
JOptionPane.showMessageDialog(null,"just finished");
}
});
firstly.start();
try {
firstly.join();
} catch (InterruptedException ex) {
Logger.getLogger(ProgressBarExample.class.getName()).log(Level.SEVERE, null, ex);
}
secondly.start();
}
});
JOptionPane.showMessageDialog(null, myPanel, "Progress bar test", JOptionPane.PLAIN_MESSAGE);
}
}
class Calculations {
public void doCaculations() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
int value = 0;
while (value < customProgressBar.getMaximum()) {
Thread.sleep(250);
value ++;
customProgressBar.setValue(value);
}
return null;
}
}.execute();
}
private void doOtherStaff(){
//more methods, that don't need to run in seperate threads, exist
}
}
There are 2 Threads.
The firstly
thread creates a Calculations
class insance and then runs a doCaculations()
method on it.
The secondly
thread pops-up a message.
The doCaculations()
method in my "real" code performs some time consuming maths and in order to simulate the time spent I added that Thread.sleep(250);
. I need to inform the user on the progress of the calculations so I am using the progressbar, that is updated by the doCaculations()
method.
I am trying to make the code work in a way that the secondly
thread runs after the firstly
thread finishes. But I cannot make it work. What happens is that the pop-up message pops-up immediately (and that means that it's thread run before I want it to run).
Note:The "just finished" message is there just to test the code. In my "real" program a method would be in it's place. I am making this note because if I just wanted a message to show I could just place it in the end of the doCaculations()
method, and everything would work fine.
I know I must be doing wrong with the Thread handling but I cannot find it. Any ideas?
PS: A thought: Actually the doCaculations()
method has its own thread. So it runs "in a SwingWorker inside a Thread". Iguess the firstly.join();
works correctly. But after the doCaculations()
method is called the fistrly
thread is considered finished, and that's why the code goes on with the secondly
thread, not knowing that the doCaculations()
thread is still doing something.
Upvotes: 0
Views: 1135
Reputation: 1804
Try
a.doCaculations();
a.join();
edit:
Since you are using SwingWorker my previous answer is incorrect, but, as in you comment, you've extended Thread, the following should work for you:
Thread a = new Calculations();
a.start();
a.join();
Don't forget, that you have to override run
method in Calculations class, like:
class Calculations extends Thread {
@Override
public void run() {
//your code here
}
}
Upvotes: 2
Reputation: 2393
Your Calculations class must extend SwingWorker. You do your calculations in doInBackground()
public class Calculations extends SwingWorker<Void, Void>{
@Override
protected Void doInBackground() throws Exception {
System.out.println("Calculating.");
Thread.sleep(3000);
return null;
}
}
And in your actionPerformed()
you use Calculations like this.
public void actionPerformed(ActionEvent e)
{
//FISRT run method
Calculations a = new Calculations();
a.execute(); // Start calculations
try {
a.get(); // Wait for calculations to finish
} catch (InterruptedException | ExecutionException e1) {
e1.printStackTrace();
}
//THEN inform that just finished
JOptionPane.showMessageDialog(null,"just finished");
}
EDIT: If you have multiple methods that you would like to run in a SwingWorker you can keep your code almost like it is. But only add these lines.
public class Calculations{
protected void calculate() {
SwingWorker sw = new SwingWorker(){
@Override
protected Object doInBackground() throws Exception {
System.out.println("Calculating.");
Thread.sleep(3000);
return null;
}
};
sw.execute(); //Start
try {
sw.get(); //Wait
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
In each method of Calculations
you create a new SwingWorker
like you did and wait for it to finish by calling SwingWorker.get();
Upvotes: 1
Reputation: 1814
In java you can use swingworker and in the done() method call your Dialog
In android you can use AsyncTask for calling the new thread and in the OnPostExecute method, call show message dialog.
Upvotes: 2