2013-09-09 3 views
1

Я читал несколько сообщений, и я не смог найти четкого ответа на мой вопрос.Повторите выполнение SwingWorker в Java

У меня есть приложение (Основной фрейм), у которого есть кнопка запуска и остановки, и только jTextArea. Когда пользователь нажимает кнопку «Старт», создается экземпляр класса SwingWorker и запускает (execute()) задачу. Эта задача - подключиться к базе данных и выполнить некоторые проверки. Для каждой проверки он корректно обновляет jTextArea, и все в порядке. Когда нажата кнопка остановки, я устанавливаю isCancelled() в true и, следовательно, фоновый процесс останавливается (у меня есть соответствующие проверки внутри SwingWorker, чтобы остановить выполнение и т. Д.).

Что я хочу сделать, когда пользователь нажимает «Начать», SwingWorker запускает выполнение, спящий на несколько минут, а затем повторяет ту же задачу. Когда кнопка «Стоп» нажата, все останавливается.

Как я могу это достичь? Я понимаю, что фоновый процесс SwingWorker должен запускаться один раз. Какими были бы другие способы сделать это? Обратите внимание, что причиной, по которой я выбрал SwingWorker, было то, что я хотел обновить jTextArea во время фонового процесса.

Заранее спасибо.

+1

SwingWorker не предназначен для этого, чтобы использовать стандартную рабочую нить, но вывод в GUI Swing должен быть завернут в invokeLater – mKorbel

ответ

5

Вы можете запускать SwingWorker один раз и только один раз, без исключения. Возможные решения включают:

  • Создайте новый объект SwingWorker каждый раз, когда нужно, запустите его и остановите и отбросьте его, когда закончите.
  • Запустите одиночный SwingWorker на протяжении всего запуска вашей программы, не отменяйте его, когда нажата кнопка остановки, а скорее pause это (как будет зависеть от части, отличной от Swing кода, о которой мы не знаем) , и awaken это когда игра нажата. Для этого может хорошо работать шаблон государственного дизайна.

Что касается вашего заявления,

То, что я хочу сделать, это когда пользователь нажимает «Пуск», то SwingWorker начинает выполнение, спит в течение нескольких минут, а затем повторно запускает ту же задачу. Когда кнопка «Стоп» нажата, все останавливается.

Рассмотрите возможность использования ScheduledExecutorService для этого внутри SwingWorker. ScheduledExecutorService создает ScheduledFuture<V>, который может быть отменен, если возникнет такая необходимость.


Редактировать
Ваши комментарии и мои ответы:

бы не ScheduledExecutorService вызвать фоновый процесс для запуска несколько раз?

Нет. Фоновый процесс будет выполняться один раз. Фьючерсы, созданные ScheduledExecutorService, также будут созданы, а затем запускаться в запланированные сроки.

Что произойдет, например, когда задержка меньше времени, затраченного на выполнение предыдущей итерации?

Будет создано несколько фьючерсов и начнет работать одновременно.

Должен ли я просто идти с петлей while внутри doInBackground() с помощью Thread.Sleep()?

Это очень сложно сказать на основе того, что мы знаем о вашем текущем проекте. Это может потенциально работать, да, но для более сложных потребностей, то нет, вы бы хотели использовать ScheduledExecutorService.

+0

, почему бы не использовать SwingWorker с таймером качания? – nachokk

+0

@nachokk: внутри 'doInBackground()' SwingWorker вы не использовали бы Swing Timer, а скорее java.util.Timer, так как он отменяется из EDT. Я много раз читал здесь, что вам лучше использовать ScheduledExecutorService вместо java.util.Timer. –

+0

@nachokk: например, проверьте [Java Timer vs ExecutorService?] (Http://stackoverflow.com/questions/409932/java-timer-vs-executorservice) –

0

Обычно я использую петлю внутри swingworker, отлично работает.

Глобальные переменные

private boolean monitor = true; 

SwingWorker Класс

private class MonitorQueue extends SwingWorker<Void, Void> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     while (monitor) { 
      System.out.println("monitor"); 
      Thread.sleep(Constants.SECOND * 5); 
     } 
     return null; 
    } 
} 

Добавлено преимущество, что у меня есть, вместо того, чтобы остановить или приостановив сам SwingWorker, я просто установить монитор = ложь. Это позволит SwingWorker завершить все задачи перед остановкой.

Смежные вопросы