![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Вопрос поднимался на форуме раз 5 (может и более, но я нашел пять). Внимательно прочитал все. Ни в одном случае не приведен код, давший нужный результат. По сути все варианты вопросов сводятся к аналогии с показом слайдов: пользователь нажимает кнопку и из процедуры обработки события нажатия кнопки (это очень важный момент) запускается процедура которая отрисовывает одну картинку, засыпет на n секунд, отрисовывает следующую и т.д.
К сожалению поток событий в Java, в отличии от, например, Delphi, не позволяет реализовать это так, как я написал. Из рекомендаций, данных разным товарищам в связи с аналогичными вопросами, я выудил ссылку на две утилиты SwingUtilities.invokeAndWaite и SwingUtilities.invokeLater. В соответствии с официальной документацией первую НЕЛЬЗЯ запускать из потока событий. Вторую вроде бы можно, но ни один из моих экспериментов не привел к нужному результату. Просьба к мастерам привести простенький (по возможности) рабочий вариант решения этой задачки и зафиксировать ее в FAQ. Заранее благодарен. -------------------- Mirkes |
|||
|
||||
| Mirkes |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Предлагаю свой вариант решения - работающий апплет.
Хотелось бы услышать мнение профессионалов (вдруг что-то сработало случайно: не знаю как в Java, а в паскале, фортране, VB это точно бывает) Код вспомогательного класса, поставляющего слайды и работающего семафором
Код главного класса
На всякий случай код пускача (классы должны лежать в подкаталоге delay того каталога, в котором лежит этот файл)/ Прошу прощения за внешний вид файла
Если решение представляет интерес могу его откомментировать (код). -------------------- Mirkes |
||||||
|
|||||||
| COVD |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
"поток событий в Java" - это, очевидно, EventDispatchThread (EDT). Это поток, который извлекает из очереди события (обьекты, имплементирующие Runnable) и выполняет их. Любое действие пользователя (например, нажатие кнопки) приводит к созданию нового события и добавление его в очередь. Все действия по изменению визуальных компонентов следует выполнять в EDT, т.е. их следует оформлять в виде событий. Это является гарантией, что изменение и перерисовка будут выполняться последовательно. Применительно к вашему коду это означает, что команду
, которая меняет содержимое метки и которая у вас выполняется в "отдельном" потоке, следует выполнить в EDT
|
||||||
|
|||||||
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Два вопроса. Во первых, насколько я понимаю вызов метода setText породит событие, которое будет занесено в очередь событий. Или я не прав? Если это не так, то тогда все методы, влекущие изменения в любом из графических компонентов (потомков от Component и Container) следует упаковывать в такую же обертку, а это заведомо не так. Во вторых, в чем причина кавычек в "отдельном" потоке? Он не отдельный? Я имел в виду отдельный от потока обработки событий (EDT). Это сообщение отредактировал(а) Mirkes - 23.8.2011, 01:52 -------------------- Mirkes |
|||
|
||||
| jk1 |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 21 Всего: 75 |
Все методы, влекущие изменения в любом из графических компонентов (потомков от Component и Container) следует упаковывать в такую же обертку если вызов происходит не из EDT. А вообще Вы стреляете из пушки по воробьям, никаких потоков в явном виде тут не нужно. Вот накидал пример через таймер:
Обратите внимание на то, что в примере отрисовка изначально запускается на EDT. Это сообщение отредактировал(а) jk1 - 23.8.2011, 13:35 -------------------- Opinions are like assholes — everybody has one |
||||
|
|||||
| COVD |
|
||||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Это просто ссылка на ваше название потока. Конечно он отдельный от EDT.
Я бы уточнил и обратил внимание на то, что в варианте jk1 используется javax.swing.Timer. И поэтому метод actionPerformed(ActionEvent e) вызывается в EDT. А если использовать java.util.Timer, то нет. И тогда надо использовать упомянутую обертку. Использование javax.swing.Timer в данном примере - изящное решение. Но отдельный поток, будь то java.util.Timer или просто new Thread(), как сделал автор топика, также применим. Изменим слегка "обертку":
Метод getNextString() теперь выполняется в отдельном от EDT потоке. Чем это хорошо? Представим, что внутри метода осуществляется запрос в базу данных, в интернет или чтение с диска. Непредсказуемо длительные операции. Если это выполнять в EDT, то возможно "замораживание" пользовательского интерфейса. Добавлено через 10 минут и 34 секунды
Что значит "в контексте вызывающего потока". Разве не в порядке общей очереди? А очередь - одна. |
||||||||
|
|||||||||
| jk1 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 21 Всего: 75 |
Конечно одна, просто неудачно выразился. Спасибо. -------------------- Opinions are like assholes — everybody has one |
|||
|
||||
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Если я правильно понимаю, вырисовалось три разных варианта решения:
1. с разными потоками без использования таймера, но с "засыпанием" исполнителя вне EDT. Годится приведенный в начале топика пример с добавлением соответствующей обертки изменений в графическом интерфейсе. 2. с таймером из java.util.Timer так же требующий обертки изменений в графическом интерфейсе. 3. с таймером из javax.swing.Timer, не требующий обертки, но грозящий "заморозкой" пользовательского интерфейса в некоторых ситуациях. Требуется мнение "Суперов" по поводу необходимости описания всех трех вариантов или только двух последних. И нужен доброволец для формирования окончательного варианта для FAQ. Я могу попытаться сделать описание методов, но уж точно не являюсь экспертом для оценки того, какие из предложенных решений стоит выносить в FAQ. Просьба отозваться тех, кто экспертами является. -------------------- Mirkes |
|||
|
||||
| Mirkes |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Прилагаю исправленный, слегка реструктуризированный (более гибкий) вариант своего решения.
Решение с таймером из javax.swing.Timer вроде вполне понятен и без переработки. Вариант с таймером из java.util.Timer мне не до конца понятен. Предлагаю следующий вариант текста для FAQ, который нуждается в дополнении третьим вариантом Постановка задачи. Необходимо организовать показ слайдов с задержкой между отображением слайдов. Возможно несколько вариантов решения этой задачи. Первый вариант оформлен как апплет, который может запускаться автономно. Создаются два специальных класса: 1. Slider - объект, который после команды "начать" начинает с заданным интервалом времени вызывать отрисовку слайдов. Фактически этот объект служит диспетчером. 2. Drawer - объект, котороый при вызове из Slider производит отрисовку очередного слайда. Он же следит за сменой слайдов. Исходно это пустышка, ничего не делающая. Наполнение при реализации. При создании Slider производится запуск отдельного потока, в котором работает только сам Slider. Большую часть времени он спит, поэтому не потребляет большого количества ресурсов. код интерфейса Drawer
Код диспетчера Slider
Код главного класса
Этот вариант работает достаточно быстро и не приводит к зависанию пользовательского интерфейса при продолжительной процедуре получения нового слайда. Второй вариант процедуры использует таймер из пакета javax.swing.Timer. События этого таймера обрабатываются в потоке событий, поетому при вызове методов, именяющих графический интерфейс, не нужно предпринимать специальных мер по передаче событий в этот поток. код примера с таймером
-------------------- Mirkes |
||||||||
|
|||||||||
| jk1 |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 21 Всего: 75 |
Вот пример реализации на java.util.Timer
-------------------- Opinions are like assholes — everybody has one |
||||
|
|||||
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Теперь есть все примеры. Если это необходимо перенести в FAQ, это должен сделать кто-то ответственный (уполномоченный). Кто может это сделать?
-------------------- Mirkes |
|||
|
||||
| jk1 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1168 Регистрация: 17.10.2008 Где: Санкт-Петербург Репутация: 21 Всего: 75 |
Необязательно. Статью в базу знаний может написать любой пользователь форума. Это сообщение отредактировал(а) jk1 - 11.10.2011, 21:56 -------------------- Opinions are like assholes — everybody has one |
|||
|
||||
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Забавно, но у меня при переходе по ссылке получен ответ "Internet Explorer не может отобразить эту веб-страницу". Переходил с разных ссылок. В чем дело? Козлит IE или упала база?
-------------------- Mirkes |
|||
|
||||
| Mirkes |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 586 Регистрация: 18.8.2011 Где: Красноярск Репутация: 2 Всего: 17 |
Необходимо поменять ссылки на базу знаний: www.base.vingrad.ru вместо стоящей сейчас base.vingrad.ru. В IE и GoogleChrome указанная на данный момент ссылка не работает.
Большое спасибо всем, принявшим участие в обсуждении. Результаты выложил в FAQ. -------------------- Mirkes |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |