многопоточность для графики Java - PullRequest
4 голосов
/ 02 ноября 2011

У меня есть Java-приложение, которое передает потоковые данные и соответственно рисует графики в реальном времени.это выполняется путем вызова методов из класса, который я написал, который использует объект Graphics.Я реализовал алгоритмы в переопределенном методе paintComponent для генерации всех графиков из самых последних данных.У меня есть другие методы в моем классе, чтобы обновить переменные, используемые в методе paintComponent для рисования графиков.

в моем основном классе я периодически обновляю свои графики в обработчике событий таймера.в обработчике событий я вызываю методы из моего класса графиков, которые обновляют определенные переменные, выполняют несколько вычислений, а затем вызывают repaint () (что, по-видимому, является правильным способом вызова метода paintComponent).

Моя проблема в том, что алгоритмы, которые я использую в методе paintComponent, могут занять (относительно) много времени для завершения в зависимости от количества и разрешения моих графиков.(я еще точно не сталкивался с этой проблемой, но сейчас пытаюсь ее решить).Конечно, я бы не хотел, чтобы весь этот график занимал все время обработки моего приложения, поэтому мне было интересно, возможно ли, чтобы «paintComponent» выполнялся в отдельном потоке.

что бы произошло, если бы я создалподкласс в моей основной для запуска в отдельном потоке и просто называется методы графа я описал?это автоматически заставило бы все эти методы (включая paintComponent) выполняться в новом потоке?или я должен был бы изменить сам мой класс графа для этого, чтобы работать?в идеале я бы хотел избежать изменения своего класса графиков, потому что я уже разработал его для работы в сборщике графического интерфейса NetBeans в качестве JPanel, и я бы хотел избежать нарушения этой функциональности.

Ответы [ 4 ]

5 голосов
/ 02 ноября 2011

Есть несколько вариантов.

Один из методов - использовать два BufferedImages, где вы рисуете один в отдельном потоке, рисуете другой, и переключаетесь, когда рисование завершается (поскольку я предполагаю, чтоснимок время от времени.)

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

Это означает, что вы будете выполнять свои алогирмы в отдельном потоке, вычислять значения, которые будут использоваться для рисования, вызывать SwingUtilities.invokeLater для обновления модели.В этом случае модель будет обновляться только в потоке Swing, и при перерисовке у вас будет доступ именно к тем данным, которые нужно нарисовать (и никаких посторонних данных).

Если эти данные все еще настолько велики, что рисуютЭто займет много времени (то есть: если вы рисуете диаграммы с тоннами точек данных), вы отправите, чтобы рассчитать, какие части вашего окна нуждаются в перекраске, и вызовите repaint () только для этого.Эта часть должна быть последним курортом как бы то ни было.99% вашей производительности будет заключаться в перемещении алгоритмов в отдельный поток и предоставлении художнику доступа к данным, которые могут быть визуализированы напрямую.

Если вы посмотрите на рекомендации по обновлению TableModel внешними данными, то у вас естьработа, которая получает данные, возникающие в фоновом потоке (обычно SwingWorker), а затем публикует их в фактической модели с помощью invokeLater () (это значит, что данные не изменяются, пока ваш paint () пытается их прочитать).затем запускает соответствующие события из обновления модели, которые сообщают таблице, какие ячейки изменились.Затем таблица знает, какая часть ее окна просмотра нуждается в перерисовке, и запускает соответствующий метод repaint ().В течение этого времени фоновый поток может продолжить извлечение данных и добавление новых обновлений в очередь событий через invokeLater.

4 голосов
/ 02 ноября 2011

Вы должны перенаправить методы рисования на SwingWorker или Runnable#Thread (все выходные данные в GUI должны быть заключены в invokeLater), например здесь или здесь

1 голос
/ 02 ноября 2011

У меня есть Java-приложение, которое передает потоковые данные и рисует в режиме реального времени. участки соответственно. это обрабатывается путем вызова методов из класса I написал, что использует объект Graphics.

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

1 голос
/ 02 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...