Двойная буферизация в Java

Я нашел этот код двойной буферизации в Интернете, но он не имеет объяснения. Я немного запутался в этом коде.

  • Почему используется образ «i»? Какая от него польза, если она используется один раз?

  • Почему мы назначаем изменение цвета цвету переднего плана, когда у нас уже есть заданный цвет?

  • Что делает метод g.drawImage()?

Вот код:

public void update(Graphics g)
{
    if(i==null)
    {
        i=createImage(getWidth(), getHeight());
        graph=i.getGraphics();
    }

    graph.setColor(getBackground());
    graph.fillRect(0, 0, getWidth(),getHeight());
    graph.setColor(getForeground());

    paint(graph);

    g.drawImage(i,0,0,this);
  }

С Уважением


person Alfred    schedule 23.11.2012    source источник
comment
Ваш код кажется очень неполным, что затрудняет выделение логики, в том числе того, откуда берется g (возможно, передается из JVM в метод paint(...) или paintComponent(...)?   -  person Hovercraft Full Of Eels    schedule 23.11.2012
comment
и Swing JComponents по умолчанию имеют двойную буферизацию   -  person mKorbel    schedule 23.11.2012
comment
Хорошо, это редактирование дает больше информации, но также вызывает больше вопросов. Метод update(Graphics g) в приложении Swing редко переопределяется, если вообще когда-либо, и обычно это делается только для приложений AWT. Ваш тег предполагает, что этот вопрос касается Swing - пожалуйста, уточните.   -  person Hovercraft Full Of Eels    schedule 23.11.2012
comment
это была ошибка. Прошу прощения за эту ошибку. Я использую его в апплете   -  person Alfred    schedule 23.11.2012
comment
Тогда этот учебник, вероятно, устарел. Я бы использовал Swing, а не AWT, поскольку, как отмечает mKorbel, рисование в Swing по умолчанию выполняется с помощью двойной буферизации.   -  person Hovercraft Full Of Eels    schedule 23.11.2012
comment
Но когда я использую JApplet, движущиеся объекты оставляют свой след. И все портится   -  person Alfred    schedule 23.11.2012
comment
@Alfred: это не имеет ничего общего с двойной буферизацией. Вы задаете неправильный вопрос. Возможно, вы не вызываете метод super paint или paintComponent. Я предлагаю вам задать новый вопрос со всеми этими важными деталями. Вы прошли базовое рисование с помощью учебных пособий Swing? Вы рисуете в методе paintComponent(...) JPanel? Вы вызываете суперметод в первой строке этого метода?   -  person Hovercraft Full Of Eels    schedule 23.11.2012


Ответы (2)


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

Двойная буферизация

Из руководств по Java, найденных здесь

Код, который у вас есть, сначала создает изображение на первом пути, которое будет вашим «задним буфером» с этим битом, я, вероятно, является полем, таким как

 private Image i;
 private Graphics graph;

 if(i==null)
{
    i=createImage(getWidth(), getHeight());
    graph=i.getGraphics();
}

Затем рисует цвет фона на изображении с помощью этого

graph.setColor(getBackground());
graph.fillRect(0, 0, getWidth(),getHeight());

Затем подготавливает лицевую сторону к рисованию.

graph.setColor(getForeground());
paint(graph); /draws

Наконец, нарисуйте задний буфер на основную поверхность.

g.drawImage(i,0,0,this);
person AbstractChaos    schedule 23.11.2012
comment
Один вопрос. Я обновляюсь только один раз, то есть в начале. После этого не обновляется. Тогда почему метод g.drawImage() не всегда печатает новую графику? - person Alfred; 24.11.2012
comment
График @Alfred является ссылкой на класс графики i, любое изменение которого влияет на изображение. - person AbstractChaos; 26.11.2012
comment
как граф стал ссылкой на класс изображения? - person Alfred; 26.11.2012
comment
@Alfred не изображение, графический класс, который на самом деле имеет методы для рисования изображения, также имеет ссылку (в силу того, что он извлекается из самого изображения) обратно на изображение, на котором он предназначен для рисования. - person AbstractChaos; 26.11.2012
comment
Итак, вы направляете меня к ссылке, созданной в условии i==null. Вы имеете в виду ссылку, созданную там, возвращая графический объект из класса изображения с помощью i.getGraphics() - person Alfred; 27.11.2012
comment
большое спасибо. :) пожалуйста, посетите мой другой вопрос здесь: stackoverflow .com/questions/13586163/ - person Alfred; 27.11.2012

Все графические операции выполняются на Graphics, полученном из i, который является растровым изображением в памяти.

По завершении растровое изображение рисуется на «реальном» (экранном) Graphics объекте g. Так пользователь никогда не увидит наполовину законченный рисунок, что исключает мерцание.

Поле i выделяется в первый раз, а затем используется повторно, поэтому оно используется не только один раз.

person Daniel Earwicker    schedule 23.11.2012