Запустите другой поток после завершения SwingWorker в Java
Я знаю, что есть много вопросов по SO, но ни один из них не дает достаточно хорошего ответа, и прежде чем задавать вопросы, я специально гуглил SO, но ничто не могло прояснить это. Я просто хочу начать другой поток, когда мой SwingWorker закончит свою работу.
Я хочу запустить таймер, когда SwingWorker заканчивает свою работу, но не могу понять, как это сделать.
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();
Теперь есть еще один поток startTimer, который я хочу запустить, когда закончится этот SwingWork.
public class startTimer implements Runnable
{
@Override
public void run()
{
while(true)
{
Thread.sleep(1000);
//Update Database
}
}
}
Но я не понимаю, как я могу это сделать?
2 ответа
Если я что-то упустил, вы можете передать ссылку в конструкторе createGUI
и начать, когда 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();
}
}
Вам также необходимо изменить
new createGUI().execute();
что-то вроде
new createGUI(new Thread(new startTimer())).execute();
Кроме того, имена классов должны начинаться с заглавной буквы. CreateGUI
а также StartTimer
Примечание: в ответе Эллиота нет ничего плохого, ожидайте, что он связывает рабочий процесс с работником и передает ссылки на объект работнику, которые в противном случае не потребовались бы (+1 к его ответу)
В качестве альтернативы передаче ссылок на классы, которые, вероятно, не должны знать или заботиться о таких вещах, вы можете использовать SwingWorker
s PropertyChangeListener
служба поддержки.
Это разъединяет работника и делает его более пригодным для повторного использования...
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();
Который просто побежит...
public class CreateGUI extends SwingWorker<Integer, Integer> {
@Override
protected Integer doInBackground() throws Exception {
// Working hard or hardly working...
return ???;
}
}
Как примечание (как меня раздражает имя рабочего), Swing НЕ является потокобезопасным, вы не должны создавать или изменять элементы пользовательского интерфейса вне потока диспетчеризации событий...
Обновление...
Если все, что вы хотите сделать, это выполнить цепочку выполнения ваших потоков, то вы можете использовать однопоточный ExecutorService
, например...
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(new CreateGUI());
es.submit(new StartTimer());
es.shutdown();
Это гарантирует, что StartTimer
не может бежать, пока CreateGUI
или заканчивает или терпит неудачу...