Структура кода в многопоточном приложении с графическим интерфейсом
Я новичок в Java и потоки в целом, и у меня есть следующее приложение с графическим интерфейсом в Java:
Во фрейме пользователь щелкает мышью в любом месте, и появляется изображение.
Как только изображение появляется, таймер реального времени начинает работать, обновляя себя в
jLabel
В зависимости от значений, которые пользователь выбрал в графическом интерфейсе, этот таймер может работать до 5 секунд.При этом воспроизводится звуковой клип. если изображение и звук совпадают, пользователь щелкает и, таким образом, останавливает таймер. Пара значений 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 поможет вам в этом. Для этого вы
- подкласс (или создать анонимный) SwingWorker
- воплощать в жизнь
doInBackground
чтобы ваш цикл синхронизации - в цикле синхронизации звоните
publish
чтобы передать метку времени (или что-то, что вы хотите поставить на этикетке) - воплощать в жизнь
process
обновить ярлык - создать экземпляр рабочего и вызвать
run
,