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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация paintComponent() 
V
    Опции темы
JavaDell
Дата 19.5.2011, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Рисую графики, получается так, что в paintComponent(), который я перегрузил, происходит много расчетов.
Расчеты основываются на текущей высоте и ширине компонента (JPanel).
Перерисовывать приходится часто, есть слайдер, меняющий цвет бэкграунда, при каждом его шевелении swing перерисовывает данный JPanel, на котором, собственно и рисую. Также ресайзы, минимайзы-максимайзы..
Для оптимизации в голову приходит только implements ComponentListener и перегруз componentResized()  componentShown().

Подскажите, как еще оптимизировать, чтобы не производить расчеты почем зря.

Это сообщение отредактировал(а) JavaDell - 19.5.2011, 15:53
PM MAIL   Вверх
Skipy
Дата 23.5.2011, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Так рисуйте график на прозрачном изображении. При изменении цвета фона перерисовываете фон, а поверх него - готовый график. График (изображение) перерисовываете через ComponentListener, это правильно Вы придумали.


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
JavaDell
Дата 24.5.2011, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм, спрошу по-другому...
Надо нарисовать несколько вертикальных осей, расстояние между ними, скажем, 50 единиц.
Также надо нарисовать кривые, идущие сквозь эти вертикали, на каждой вертикальной прямой есть точка, через которую одна из кривых проходит.
Кривых множесво и некоторые из них могут выходить за пределы вертикальных линий. (если ось со значениями от 20 до 100, то кривая в точку 0 уйдет ниже оси)
Ползунком JSlider'а надо менять цвет только панели с вертикальными линиями.
Надеюсь доходчиво объяснил. Пример здесь: http://www.infovis.net/imagenes/T1_N112_A12_CParalelas.gif
Вот не могу придумать как бы это получше реализовать, тобы не вызывать repaint() по 10 раз.

Добавлено через 7 минут и 22 секунды
Пока пробовал с двумя панелями, одна большая, другая поменьше внутри нее.
На внешней рисую кривые, на внутренней - оси.
Пытался сделать внутреннюю прозрачной, а на внешней сделать так:
Код

Graphics g = getGraphics();
g.setColor..blablabla...
g.fillRect(параметры внутренней панели);
 
При отрисовке получается ужас.
PM MAIL   Вверх
Skipy
Дата 25.5.2011, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Еще раз. Графики Вы рисуете на прозрачном изображении. Не на панели - на изображении, экземпляре BufferedImage нужного размера, типа INT_ARGB. И рисуете их вместе с осями. 

Отрисовка происходит так. Сначала Вы заполняете фон (если выставите нужный цвет фона через setBackground и вызовете super.paintComponent() - это произойдет автоматически, панель не прозрачная должна быть). Потом отрисовываете сам рисунок с графиками, одним движением. Это произойдет очень быстро.

И пусть перерисовка происходит множество раз при движении слайдера - Вы будете только менять цвет фона. Само изображение (графики) не придется пересчитывать, это надо только при изменении размера.

Это сообщение отредактировал(а) Skipy - 25.5.2011, 10:43


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
JavaDell
Дата 25.5.2011, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Понял, спасибо.
Пока писал, наткнулся на проблемку: как именно накладывать рисунок на панель?
Я использую JLayeredPane, но чего-то оно не очень работает.
Приложу код, там я делаю 2 панели, одну главную (она потом будет нужна), вторую для цвета сверху и пытаюсь наложить с помощью layered pane еще одну панель (просто для теста, на самом деле здесь будет изображение), но она, видимо, закрывает собой ниже лежащие, даже если прописано setOpaque(false).
Буду благодарен, если подскажете в чем дело.

Это сообщение отредактировал(а) JavaDell - 25.5.2011, 17:16

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  view.zip 0,96 Kb
PM MAIL   Вверх
Skipy
Дата 25.5.2011, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Цитата(JavaDell @ 25.5.2011,  17:14)
Пока писал, наткнулся на проблемку: как именно накладывать рисунок на панель?

Код
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.drawImage(myGraphImage, 0, 0, this);
}


P.S. Вот тут есть примеры с использованием BufferedImage и его отрисовкой на компоненте: http://www.skipy.ru/technics/gui_int.html

Это сообщение отредактировал(а) Skipy - 25.5.2011, 17:17


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
JavaDell
Дата 26.5.2011, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вопрос в том, как наложить, а не как нарисовать.
Если я перегружу paintComponent() той панели, на которой мне надо рисовать, сверху будет еще одна, не прозрачная панель, на которой меняется цвет, и рисунка видно не будет.
Посмотрите код, который я приложил.
PM MAIL   Вверх
Skipy
Дата 26.5.2011, 10:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Вам нужна одна панель. Одна, в скобках прописью - одна. Цвет Вы выставляете на этой панели через setBackground. Графики рисуете на этой же панели, через прозрачное изображение и переопределение paintComponent. Я уже не знаю, как понятнее объяснить.


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
JavaDell
Дата 26.5.2011, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за помощь.

Это сообщение отредактировал(а) JavaDell - 26.5.2011, 15:18
PM MAIL   Вверх
Skipy
Дата 26.5.2011, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

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



Вот примерная реализация:

Код
package ru.skipy.tests.components;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

/**
 * HSVSlider
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 26.05.2011
 */
public class HSVSlider extends JPanel {

    private HSVPanel hsvPanel;
    private JSlider slider;

    public HSVSlider() {
        setLayout(new GridBagLayout());
        hsvPanel = new HSVPanel();
        slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
        slider.setPaintLabels(false);
        slider.setPaintTicks(false);
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                hsvPanel.position = slider.getValue();
                hsvPanel.repaint();
            }
        });
        add(slider, new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.CENTER,
                GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
        add(hsvPanel, new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.CENTER,
                GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
        setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.gray),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)));
    }

    public void addChangeListener(ChangeListener listener) {
        slider.addChangeListener(listener);
    }

    public int getValue() {
        return slider.getValue();
    }

    public void setValue(int value) {
        slider.setValue(value);
    }

    private class HSVPanel extends JPanel {

        private int position;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(360, 25);
        }

        @Override
        protected void paintComponent(Graphics g) {
            int w = getWidth() - 1;
            int h = getHeight();
            if (g instanceof Graphics2D) {
                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
            }
            for (int i = 0; i <= w; i++) {
                g.setColor(Color.getHSBColor(i / ((float) w), 1, 1));
                g.drawLine(i, 0, i, h);
            }
            g.setColor(Color.black);
            int p = (int) (position / 360f * w);
            g.drawLine(p, 0, p, h);
        }
    }
}


Код
package ru.skipy.tests.components;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

/**
 * HSVSliderTest
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 26.05.2011
 */
public class HSVSliderTest extends JFrame {

    public HSVSliderTest() {
        super("HSBSlider test");
        JPanel cp = new JPanel(new BorderLayout(5, 5));
        cp.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        final HSVSlider hsvSlider = new HSVSlider();
        cp.add(hsvSlider, BorderLayout.SOUTH);
        final JPanel p = new JPanel() {

            BufferedImage img;

            {
                img = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = img.createGraphics();
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setStroke(new BasicStroke(3));
                g.setPaint(Color.lightGray);
                g.draw(new Ellipse2D.Float(60, 10, 80, 180));
                g.draw(new Ellipse2D.Float(10, 60, 180, 80));
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(img, (getWidth() - 200) / 2, (getHeight() - 200) / 2, this);
            }
        };
        p.setBorder(BorderFactory.createLineBorder(Color.black));
        hsvSlider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                p.setBackground(Color.getHSBColor(hsvSlider.getValue() / 360f, 1, 1));
                p.repaint();
            }
        });
        hsvSlider.setValue(1);
        hsvSlider.setValue(0);
        cp.add(p, BorderLayout.CENTER);
        setContentPane(cp);
        setSize(400, 350);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new HSVSliderTest().setVisible(true);
    }
}


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

Это сообщение отредактировал(а) Skipy - 26.5.2011, 17:30


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0528 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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