Структура кода в многопоточном приложении с графическим интерфейсом

Я новичок в Java и потоки в целом, и у меня есть следующее приложение с графическим интерфейсом в Java:

  1. Во фрейме пользователь щелкает мышью в любом месте, и появляется изображение.

  2. Как только изображение появляется, таймер реального времени начинает работать, обновляя себя в jLabelВ зависимости от значений, которые пользователь выбрал в графическом интерфейсе, этот таймер может работать до 5 секунд.

  3. При этом воспроизводится звуковой клип. если изображение и звук совпадают, пользователь щелкает и, таким образом, останавливает таймер. Пара значений jLabel обновляется для отражения совпадения или пропуска. Если нет, пользователь бездействует и ожидает изменения пары изображения / аудиоклипа после истечения таймера. Если либо пользователь останавливает таймер, либо таймер заканчивается, приложение ожидает предварительно выбранного значения периода времени между изображениями и переходит к следующему значению изображения / звука.

У меня есть следующая структура:

Я звоню

while(true)
{
SwingUtilities.invokeAndWait(displayTimer);
}

в моем run() метод.

мой Runnable является

private final Runnable displayTimer= new Runnable()
{
public void run()
{
 displayElapsed(System.currentTimeMillis() - startTime);
}

};

с startTime инициализируется позже и является отправной точкой для начала задачи.

мой displayElapsed()Метод беспорядочный, проверяет, остановился ли таймер с помощью ввода или бездействия пользователя. Если нет, то он обновляет jLabel ответственность за таймер. Если это так, он вызывает startInteraction() метод.

startInteraction() подготавливает новое изображение и звук, отображает и воспроизводит каждый соответственно, создает новую тему updater и начинает это.

у меня тоже есть mouseListener который слушает ввод пользователя. Это вызывает updater.interrupt() по клику пользователя.

Теперь вопрос. Я знаю, что колебание небезопасно. В поведении определенно есть икоты, поскольку иногда он не отвечает на щелчки мышью пользователя сразу, а иногда проходит две пары изображения / звука без должного количества ожидания. Ярлыки также не обновляются сразу.

В общем, структура выглядит как беспорядок, который я не могу объяснить логически.

Все, что я знаю, я начинаю новую тему для каждого displayElapsed Я делаю это и прерываю его каждый раз, когда происходит остановка пользователя или остановка. Так что технически каждый поток должен быть в последовательности.

Должен быть намного лучший способ сделать это, и я хотел посмотреть, что будет хорошим началом в переписывании этого.

1 ответ

Взгляните на эту статью о SwingWorker. Проблемы, с которыми сталкивается ваша программа, заключаются в том, что поток диспетчеризации событий (который является единственным потоком, используемым для визуализации пользовательского интерфейса) блокируется вашим бесконечным циклом, поскольку выполняемый файл выполняется синхронно в EDT.

Вам нужно запустить код таймера в другой ветке и в этой ветке публиковать периодические задания для обновления метки в EDT. Класс SwingWorker поможет вам в этом. Для этого вы

  1. подкласс (или создать анонимный) SwingWorker
  2. воплощать в жизнь doInBackground чтобы ваш цикл синхронизации
  3. в цикле синхронизации звоните publish чтобы передать метку времени (или что-то, что вы хотите поставить на этикетке)
  4. воплощать в жизнь process обновить ярлык
  5. создать экземпляр рабочего и вызвать run,
Другие вопросы по тегам