Reputation:
I know there many questions on SO but non of them has good enough answer and before asking here I googled a lot specially SO but nothing could make it clear. I just simply wants to start my other thread when my SwingWorker finish its work.
I want to start a timer when the SwingWorker finishes it's work but cannot figure out how.
class createGUI extends SwingWorker<Void, Void>
{
@Override
protected Integer doInBackground() throws Exception
{
//Some long processing
}
@Override
protected void done()
{
//Doing GUI work here
prgBar.setInderminent(false);
}
}
//Starts a progressBar and calls createGUI();
prgBar.setInderminent(true);
new createGUI().execute();
Now there is another startTimer Thread which I want to start when this SwingWork finishes.
public class startTimer implements Runnable
{
@Override
public void run()
{
while(true)
{
Thread.sleep(1000);
//Update Database
}
}
}
But I don't understand how can I do so?
Upvotes: 1
Views: 624
Reputation: 347204
Note: There is nothing wrong with Elliot's answer, expect that it couples the work flow to the worker and passes object references to the worker, which it would otherwise not require (+1 to his answer)
As an alternative to passing about references to classes which probably don't need to know or care about such things, you could use the SwingWorker
s PropertyChangeListener
support.
This decouples the worker and makes it more reusable...
CreateGUI worker = new CreateGUI();
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("state".equals(evt.getPropertyName())) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
prgBar.setInderminent(false);
startTimer.start();
break;
}
}
}
});
worker.execute();
Which would simply run...
public class CreateGUI extends SwingWorker<Integer, Integer> {
@Override
protected Integer doInBackground() throws Exception {
// Working hard or hardly working...
return ???;
}
}
Just as a side note (as the worker name freaks me out), Swing is NOT thread safe, you should not create or modify UI elements from outside the Event Dispatching Thread...
Updated...
If all you want to do is chain the execution of your threads, then you could use a single threaded ExecutorService
, for example...
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new CreateGUI());
es.submit(new StartTimer());
es.shutdown();
This ensures that StartTimer
can't run until CreateGUI
either finishes or fails...
Upvotes: 1
Reputation: 201447
Unless I'm missing something, you could pass a reference in the constructor to createGUI
and start that when done()
.
class createGUI extends SwingWorker<Void, Void>
{
private Thread startTimer;
public createGUI(Thread startTimer) {
this.startTimer = startTimer;
}
@Override
protected Integer doInBackground() throws Exception {
//Some long processing
}
@Override
protected void done()
{
//Doing GUI work here
prgBar.setInderminent(false);
startTimer.start();
}
}
You would also need to change
new createGUI().execute();
to something like
new createGUI(new Thread(new startTimer())).execute();
Also, class names should start with a capital letter. CreateGUI
and StartTimer
Upvotes: 3