Почему мой jscrollpane приводит к нечетным вызовам рисования в java swing? - PullRequest
5 голосов
/ 19 февраля 2009

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

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

Например, если мой видовой экран имеет размер 245x195 и я прокручиваю вниз на 3 пикселя, моя процедура рисования вызывается с g.getClipBounds(), установленным следующим образом:

java.awt.Rectangle[x=0,y=195,width=245,height=3]
java.awt.Rectangle[x=0,y=3,width=245,height=195]

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

  1. Кто-нибудь знает, как предотвратить 2-й вызов рисования? Это то, что я делаю здесь в духе jane в стиле jane: у меня есть компонент, я добавляю его в область прокрутки и добавляю полоса прокрутки к родительскому компоненту. Вы можете увидеть это поведение даже в первой демонстрации прокрутки изображений @ учебник по качелям .

  2. Если ответом на вопрос № 1 является «Нет»: Кто-нибудь может придумать, как с этим справиться? Должен ли я рисовать в каком-либо буфере изображения, отслеживать последние вызовы рисования и скопировать изображение, где это возможно? Я не могу представить, что это намного быстрее, чем повторное рендеринг, но любая оценка приветствуется: -)

1 Ответ

4 голосов
/ 19 февраля 2009

Я столкнулся с этой проблемой в мире .NET. Двойная буферизация должна решить вашу проблему.

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

Если вы начнете свою логику рендеринга с очистки до цвета фона, то это будет выглядеть как вспышка. Двойная буферизация предотвращает это, потому что она всегда отображается из завершенного рендера. Худшее, что может случиться, - это легкие «разрывы», но это заметно только в быстро меняющихся анимациях.

Даже если вы хотите визуализировать только часть гигантского изображения, вы все равно можете использовать эту технику. Просто визуализируйте то, что вам нужно, на внеэкранной поверхности (размер видимой части которого вы хотите). А затем, когда вы закончите, нарисуйте все изображение на поверхность дисплея одним махом.

...