| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: GUI и Java FX приложения > Оптимизация paintComponent() |
| Автор: JavaDell 19.5.2011, 15:51 |
| Рисую графики, получается так, что в paintComponent(), который я перегрузил, происходит много расчетов. Расчеты основываются на текущей высоте и ширине компонента (JPanel). Перерисовывать приходится часто, есть слайдер, меняющий цвет бэкграунда, при каждом его шевелении swing перерисовывает данный JPanel, на котором, собственно и рисую. Также ресайзы, минимайзы-максимайзы.. Для оптимизации в голову приходит только implements ComponentListener и перегруз componentResized() componentShown(). Подскажите, как еще оптимизировать, чтобы не производить расчеты почем зря. |
| Автор: Skipy 23.5.2011, 10:30 |
| Так рисуйте график на прозрачном изображении. При изменении цвета фона перерисовываете фон, а поверх него - готовый график. График (изображение) перерисовываете через ComponentListener, это правильно Вы придумали. |
| Автор: JavaDell 24.5.2011, 22:14 | ||
| Хм, спрошу по-другому... Надо нарисовать несколько вертикальных осей, расстояние между ними, скажем, 50 единиц. Также надо нарисовать кривые, идущие сквозь эти вертикали, на каждой вертикальной прямой есть точка, через которую одна из кривых проходит. Кривых множесво и некоторые из них могут выходить за пределы вертикальных линий. (если ось со значениями от 20 до 100, то кривая в точку 0 уйдет ниже оси) Ползунком JSlider'а надо менять цвет только панели с вертикальными линиями. Надеюсь доходчиво объяснил. Пример здесь: http://www.infovis.net/imagenes/T1_N112_A12_CParalelas.gif Вот не могу придумать как бы это получше реализовать, тобы не вызывать repaint() по 10 раз. Добавлено через 7 минут и 22 секунды Пока пробовал с двумя панелями, одна большая, другая поменьше внутри нее. На внешней рисую кривые, на внутренней - оси. Пытался сделать внутреннюю прозрачной, а на внешней сделать так:
При отрисовке получается ужас. |
| Автор: Skipy 25.5.2011, 10:42 |
| Еще раз. Графики Вы рисуете на прозрачном изображении. Не на панели - на изображении, экземпляре BufferedImage нужного размера, типа INT_ARGB. И рисуете их вместе с осями. Отрисовка происходит так. Сначала Вы заполняете фон (если выставите нужный цвет фона через setBackground и вызовете super.paintComponent() - это произойдет автоматически, панель не прозрачная должна быть). Потом отрисовываете сам рисунок с графиками, одним движением. Это произойдет очень быстро. И пусть перерисовка происходит множество раз при движении слайдера - Вы будете только менять цвет фона. Само изображение (графики) не придется пересчитывать, это надо только при изменении размера. |
| Автор: JavaDell 25.5.2011, 17:14 |
| Понял, спасибо. Пока писал, наткнулся на проблемку: как именно накладывать рисунок на панель? Я использую JLayeredPane, но чего-то оно не очень работает. Приложу код, там я делаю 2 панели, одну главную (она потом будет нужна), вторую для цвета сверху и пытаюсь наложить с помощью layered pane еще одну панель (просто для теста, на самом деле здесь будет изображение), но она, видимо, закрывает собой ниже лежащие, даже если прописано setOpaque(false). Буду благодарен, если подскажете в чем дело. |
| Автор: Skipy 25.5.2011, 17:16 | ||||
P.S. Вот тут есть примеры с использованием BufferedImage и его отрисовкой на компоненте: http://www.skipy.ru/technics/gui_int.html |
| Автор: JavaDell 26.5.2011, 09:18 |
| Вопрос в том, как наложить, а не как нарисовать. Если я перегружу paintComponent() той панели, на которой мне надо рисовать, сверху будет еще одна, не прозрачная панель, на которой меняется цвет, и рисунка видно не будет. Посмотрите код, который я приложил. |
| Автор: Skipy 26.5.2011, 10:09 |
| Вам нужна одна панель. Одна, в скобках прописью - одна. Цвет Вы выставляете на этой панели через setBackground. Графики рисуете на этой же панели, через прозрачное изображение и переопределение paintComponent. Я уже не знаю, как понятнее объяснить. |
| Автор: JavaDell 26.5.2011, 14:26 |
| Спасибо за помощь. |
| Автор: Skipy 26.5.2011, 17:28 | ||||
Вот примерная реализация:
На панели отрисовывается изображение из буфера. Размер буфера не меняется вместе с компонентой, но это сделать несложно, в статье, которую я приводил выше, это есть. |