Должен ли я применить шаблон состояния здесь? - PullRequest
0 голосов
/ 02 мая 2009

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

Мой paintComponent имеет только операторы if:

if(!extraOnly) //paint something

paint something

if(listener.getRectangle() != null) // Paint something

Мне нравится идея использования шаблона состояния, но я не уверен, что это подходящий момент для его использования? Мне не нравится идея установить логическое значение для extraOnly, и, возможно, во мне также появилась шаблонная лихорадка :). Каждое состояние будет иметь только один метод draw (Graphics g)

Поскольку это часть представления моего приложения в шаблоне MVC, я также не уверен, что использование шаблона состояния неверно. Разве состояние не должно быть частью модели, а не представления?

Ответы [ 3 ]

1 голос
/ 02 мая 2009

Я не вижу ничего плохого в том, чтобы иметь состояние в представлении. Это явно не то же самое состояние, что и в модели.

Примером может служить веб-браузер. Модель в этом случае - DOM веб-страницы, и представление браузера отображает DOM в виде экрана. При прокрутке вниз по веб-странице было бы очень неэффективно делать DOM на каждом кадре. Очевидно, что буферное состояние является решением этой проблемы. Состояние должно быть обновлено только в случае изменения основного DOM.

0 голосов
/ 02 мая 2009

Общий большой вопрос, кажется, состоит в том, как сделать эффективную живопись?

Частичное рисование - хороший способ улучшить производительность, если рисование идет медленно.

Однако сначала докажите, что рисование идет медленно! Если профилирование показывает, что рисование является проблемой, вы можете перейти к частичному обновлению.

Один из подходов заключается в использовании «отслеживания грязных прямоугольников». Это очень широко используемая вещь, и такие термины, как «аннулирование» (область, которая нуждается в перерисовке) и «проверка» (акт рисования грязного бита). Оконная система почти наверняка уже делает это, так что может случиться так, что вы можете воспользоваться этим, например, Java Swing RepaintManager хранит ограничивающий прямоугольник грязной области.

Тем не менее, вы можете легко бросить свой собственный. У вас может быть переменная-член - «регион», или просто список прямоугольников в векторе, или ограничительный прямоугольник - для представления области, которая будет обновлена ​​на следующем рисунке. В вашем конструкторе или обработчиках с измененным размером инициализируйте это для всей области. В любое время, когда вы хотите перерисовать часть панели, аннулируйте эту часть, добавив прямоугольник в грязную область. При рисовании рисуйте только части в грязной области, а затем очищайте грязную область. Частичное рисование таким образом хорошо работает, например, с буферизованными изображениями. Легко!

0 голосов
/ 02 мая 2009

как насчет списка элементов для рисования, каждый с уровнем z и грязным флагом? так что ваша краска может выглядеть так:

paint()
{
    sort(drawables, by z-level)
    foreach(drawable in drawables)
       if (drawable.isDirty())
           drawable.paint()
}

вам нужно будет рассмотреть возможность загрязнения перекрывающихся объектов, но обычно этот подход довольно прост в реализации.

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

...