2015-10-08 2 views
0

С нескольких дней я немного играл в маленькой игре в java.Вызов перерисовки в нескольких потоках?

Это вредит java swing, когда 2 потока называют repaint() одновременно?

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

В теории перекраска тогда может быть вызвана двумя потоками одновременно.

+0

можете ли вы вставить свой код? – Vishal

+0

@ Vishal довольно большой, но пример действительно был бы лучше, но это были 2 потока, один из них переименовал в качестве ответа на нажатие кнопки (edt), а другой - просто нормальный поток java (x extends Thread) –

ответ

2

Фактически repaint() может быть вызван в то же время в этом случае. Но это не проблема.

На самом деле методы, подобные repaint(), revalidate(), безопасны в использовании в любых потоках. Эти методы фактически отправляют запросы на EDT (Thread Dispatch Thread) для вызова paint() и validate(). Поэтому, если вы вызываете repaint() много раз, используя разные потоки, он ставит в очередь запрос на вызов paint().

Нажмите here для получения дополнительной информации о EDT.

Нельзя назвать метод paint(), не используя EDT. (Лучше, если вы не позвоните навсегда.) Но вызов repaint() в то же время с использованием разных потоков не будет проблемой.

+0

hotzst вызвал у меня немного беспокойство, потому что я вызывал перерисовку из не-edt-потока и помнил, что это может быть неправильно, потому что большую часть времени, с которым связаны связанные с ui вещи, не следует напрямую обращаться из такого потока. Но повезло, что вы пришли. Действительно, кажется, что вы можете безопасно переписывать текст из не-edt-потока (простой поток java). Спасибо за полезный ответ! –

+0

repaint выполняется с помощью 'RepaintManager' после того, как вы вызвали метод' repaint() 'из любого потока. 'RepaintManager' выполнит свою работу правильно и покрасит компоненты, и нам не нужно беспокоиться об этом. –

+0

Является ли менеджер RepaintManager достаточно умным, чтобы рисовать только один раз, если перед рисованием произошло несколько вызовов' repaint() '? – gdbj

1

Вы не можете. Все обновления графического интерфейса должны выполняться одним и тем же потоком пользовательского интерфейса. Это справедливо не только для приложений Swing, но и для других интерфейсов пользовательского интерфейса и на других языках. Что вы можете сделать, так это подготовить обновление пользовательского интерфейса в другом потоке и затем делегировать последний шаг в пользовательский интерфейс, который обновляет графический интерфейс.