![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 1 Всего: 11 |
Я написал несколько потоков, которые на заднем плане выполняют длительные операции, не мешая графическому интерфейсу. Однако, я обнаружил, что эти потоки всё же мешают интерфейсу.
Я думаю, что причина в том, что мои потоки постоянно постят в Свинг всякие сообщения. Например, один поток читает файл и заполняет структуру в памяти. При этом он постоянно сообщает окну прогресса о возникающих ошибках в данных. Делается это при помоши invokeLater, но, насколько я понимаю, настолько часто, что интерфейс всё же тормозит. Может ли такое быть и как правильно поступить? Я хочу, чтобы у меня список заполнялся прямо на ходу и было прям видно, как добавляются элементы и как меняется длина ползунка в полосе прокрутки. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Можно прореживать. Если загружается 10000 строк, то обновлять полосу прокрутки на каждой сотой строке, например. т.е. обновлять прогресс бар с шагом не меньше 1%.
|
|||
|
||||
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 1 Всего: 11 |
С полосой прокрутки понятно. У меня в интерфейсе стоит таймер и интерфейс сам раз в секунду опрашивает поток и обновляет себе прогресс. Тут никаких проблем не возникает. А вот когда я хочу из параллельного потока асинхронно заполнить таблицу (большую) или список, то начинаются тормоза.
|
|||
|
||||
| COVD |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
а я из первого сообщения понял наоборот, что поток, поставляющий данные, обновляет прогресс бар ("При этом он постоянно сообщает окну прогресса ...")
Тут важно чтобы таблица не перерисовывалась на каждой добавленной строке. Перерисовывать таблицу имеет смысл не чаще, чем 1-2 раза в секунду. |
||||
|
|||||
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 1 Всего: 11 |
Ну в общем, поток обновляет, но не прогресс бар, а таблицу.
А как сделать, чтобы таблица перерисовывалась реже? Поток добавляет данные в модель таблицы, и делает это при помощи invokeLater. То есть, кладёт команды о добавлении в очередь Свинга. Когда очередь доходит, то данные добавдяются, модель таблицы автоматически уведомляет таблицу и она сама перерисовывается. Всё это в одном EventDispatchThread, как я понимаю. Как можно сделать, чтоб не перерисовывалась? |
|||
|
||||
| kkorsakoff |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.10.2005 Где: Санкт-Петербург Репутация: нет Всего: 14 |
А как вы добавляете данные в модель? По идее если реализовать модель для таблицы как подкласс AbstractTableModel, то данные можно добавлять во "внутреннее хранилище данных модели". Тогда таблица автоматически не будет перерисовываться при каждом добавлении. А для перерисовки самостоятельно вызывать с некоторой периодичностью fireTableRowsInserted(index, index)
Добавлено через 2 минуты и 13 секунд Тогда добавлять данные можно даже не в EDT (если конечно обеспечить синхронизацию хранилища данных модели), а EDT только будет отрабатывать fireTableRowsInserted с такой периодичностью, с которой пожелаете. |
|||
|
||||
| Dims |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1016 Регистрация: 21.11.2006 Репутация: 1 Всего: 11 |
Что такое EDT?
Ну да, у меня функция fire* автоматически вызывается в процедуре добавления данных в модель. Вроде бы, так должно быть. Если так не сделать, то, насколько я понимаю, будет проявляться мусор при перемещении окна? |
|||
|
||||
| kkorsakoff |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.10.2005 Где: Санкт-Петербург Репутация: нет Всего: 14 |
EDT - Event Dispatch Thread
Мусора не будет, т.к. таблица еще знать не будет о новых строках. Тут уж приходится выбирать: или gui, знающий о обновлениях в модели "порциями" или тормоза |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
согласен c kkorsakov. Таблица узнает об изменении модели по событию и это событие можно зажигать с прореживанием. Но это все замечательно, если строки просто добавляются в конец и никаких удалений. При удалении наверное надо сразу информировать.
С другой стороны, в событии можно указать номер строки и перерисовываться должна не все таблица, а только необходимая строка. Ассортимент событий создан именно с целью избавления от тормозов. Но у меня не всегда получалось. Приходилось перерисовывать все. Это сообщение отредактировал(а) COVD - 26.12.2007, 05:16 |
|||
|
||||
| LSD |
|
|||
![]() 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. |
|||
|
||||
![]()
|
| Правила форума "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. |