Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильно написать WorkerThread для Swing 
:(
    Опции темы
Dims
Дата 20.12.2007, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



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

Я думаю, что причина в том, что мои потоки постоянно постят в Свинг всякие сообщения. Например, один поток читает файл и заполняет структуру в памяти. При этом он постоянно сообщает окну прогресса о возникающих ошибках в данных. Делается это при помоши invokeLater, но, насколько я понимаю, настолько часто, что интерфейс всё же тормозит.

Может ли такое быть и как правильно поступить?

Я хочу, чтобы у меня список заполнялся прямо на ходу и было прям видно, как добавляются элементы и как меняется длина ползунка в полосе прокрутки.
PM MAIL   Вверх
COVD
Дата 20.12.2007, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



Можно прореживать. Если загружается 10000 строк, то обновлять полосу прокрутки на каждой сотой строке, например. т.е. обновлять прогресс бар с шагом не меньше 1%.
PM MAIL   Вверх
Dims
Дата 21.12.2007, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



С полосой прокрутки понятно. У меня в интерфейсе стоит таймер и интерфейс сам раз в секунду опрашивает поток и обновляет себе прогресс. Тут никаких проблем не возникает. А вот когда я хочу из параллельного потока асинхронно заполнить таблицу (большую) или список, то начинаются тормоза.
PM MAIL   Вверх
COVD
Дата 21.12.2007, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



Цитата

У меня в интерфейсе стоит таймер и интерфейс сам раз в секунду опрашивает 


а я из первого сообщения понял наоборот, что поток, поставляющий данные, обновляет прогресс бар ("При этом он постоянно сообщает окну прогресса ...")

Цитата

А вот когда я хочу из параллельного потока асинхронно заполнить таблицу (большую) или список, то начинаются тормоза. 


Тут важно чтобы таблица не перерисовывалась на каждой добавленной строке. Перерисовывать таблицу имеет смысл не чаще, чем 1-2 раза в секунду. 



PM MAIL   Вверх
Dims
Дата 22.12.2007, 02:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



Ну в общем, поток обновляет, но не прогресс бар, а таблицу.

А как сделать, чтобы таблица перерисовывалась реже? Поток добавляет данные в модель таблицы, и делает это при помощи invokeLater. То есть, кладёт команды о добавлении в очередь Свинга. Когда очередь доходит, то данные добавдяются, модель таблицы автоматически уведомляет таблицу и она сама перерисовывается. Всё это в одном EventDispatchThread, как я понимаю. 

Как можно сделать, чтоб не перерисовывалась?
PM MAIL   Вверх
kkorsakoff
Дата 23.12.2007, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.10.2005
Где: Санкт-Петербург

Репутация: нет
Всего: 14



А как вы добавляете данные в модель? По идее если реализовать модель для таблицы как подкласс AbstractTableModel, то данные можно добавлять во "внутреннее хранилище данных модели". Тогда таблица автоматически не будет перерисовываться при каждом добавлении. А для перерисовки самостоятельно вызывать с некоторой периодичностью  fireTableRowsInserted(index, index)

Добавлено через 2 минуты и 13 секунд
Тогда добавлять данные можно даже не в EDT (если конечно обеспечить синхронизацию хранилища данных модели), а EDT только будет отрабатывать fireTableRowsInserted с такой периодичностью, с которой пожелаете.
PM MAIL WWW ICQ   Вверх
Dims
Дата 23.12.2007, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1016
Регистрация: 21.11.2006

Репутация: 1
Всего: 11



Что такое EDT?

Ну да, у меня функция fire* автоматически вызывается в процедуре добавления данных в модель. Вроде бы, так должно быть. Если так не сделать, то, насколько я понимаю, будет проявляться мусор при перемещении окна?
PM MAIL   Вверх
kkorsakoff
Дата 24.12.2007, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.10.2005
Где: Санкт-Петербург

Репутация: нет
Всего: 14



EDT - Event Dispatch Thread

Мусора не будет, т.к. таблица еще знать не будет о новых строках.
Тут уж приходится выбирать: или gui, знающий о обновлениях в модели "порциями" или тормоза
PM MAIL WWW ICQ   Вверх
COVD
Дата 26.12.2007, 05:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



согласен c kkorsakov. Таблица узнает об изменении модели по событию и это событие можно зажигать с прореживанием. Но это все замечательно, если строки просто добавляются в конец и никаких удалений. При удалении наверное надо сразу информировать. 

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

Это сообщение отредактировал(а) COVD - 26.12.2007, 05:16
PM MAIL   Вверх
LSD
Дата 26.12.2007, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 38
Всего: 538



Я бы сделал метод batchInsert() который бы вставлял не одну строку, а несколько.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0660 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.