Хорошо, значит, вы, кажется, бьетесь против некоторой дезинформации и недопонимания. Возможно, вам следует начать с рассмотрения чего-то вроде paintComponent () против paint () и JPanel против Canvas в графическом интерфейсе типа кисти
В AWT / Swing есть как минимум два способа выполнения нестандартной живописи, каждый со своими плюсами и минусами.
Вы можете использовать paintComponent
, который "зацепит" систему рисования, используемую Swing. Swing использует «пассивную» систему рендеринга. Это означает, что вы не можете контролировать, когда что-то раскрашивается, система рисования принимает эти решения и затем (косвенно) вызывает paintComponent
вашего компонента, чтобы вы могли выполнять обновления.
Другой механизм (BufferStrategy
) использует «активную» систему рендеринга, которая дает вам полный контроль над процессом рисования.
Как правило, их нельзя смешивать. Swing имеет свою собственную систему рисования и не будет хорошо работать с BufferStrategy
, поэтому это означает, что если вы хотите использовать компоненты Swing в качестве выходных данных, вы не можете.
Но это не ответит на ваш вопрос, или не напрямую
Давайте попробуем сломать его
gameRender
private void gameRender() {
if (DoubleBufferImage == null) {
System.out.println("The Image is null: Error occurence");
DoubleBufferImage = createImage(P_WIDTH - 15, P_HEIGHT - 15);
}
DoubleBufferGraphic = DoubleBufferImage.getGraphics();
DoubleBufferGraphic.setColor(Color.LIGHT_GRAY);
DoubleBufferGraphic.fillRect(0, 0, P_WIDTH, P_HEIGHT);
DoubleBufferGraphic.setColor(Color.BLUE);
DoubleBufferGraphic.setFont(font);
DoubleBufferGraphic.drawString("Average FPS/UPS: " +
df.format(averageFPS) + df.format(averageUPS), 10, 10);
}
В данный момент DoubleBufferImage
кажется BufferedImage
, поэтому, когда вызывается gameRender
, он проверяет, существует ли буфер, и создает его по мере необходимости. Затем он берет ссылку на контекст DoubleBufferImage
s Graphics
и подготавливает ее для рендеринга, удаляя то, что было ранее нарисовано в нем.
Краткий обзор Graphics
Graphics
- это абстрактный слой поверх базового конвейера рендеринга, который часто реализуется с использованием OpenGL или DirectX в зависимости от системы. Он обеспечивает общий уровень, на котором графические операции могут выполняться независимо от системы
paintScreen
public void paintScreen() {
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (DoubleBufferImage != null)) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync();
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
Это меня беспокоит, так как у меня нет контекста, но this.getGraphics()
, кажется, берет ссылку на контекст Graphics
компонента и рисует DoubleBufferImage
к нему.
Это опасно и не рекомендуется. getGraphics
возвращает снимок компонента с момента его последней закраски, который можно закрасить в любое время, когда компонент закрашивается снова.
Вы должны при первой же возможности избавиться от этого метода.
paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (DoubleBufferImage != null) {
g.drawImage(DoubleBufferImage, 0, 0, null);
}
}
Как упомянуто выше, paintComponent
является предпочтительным методом подключения системы окраски Swing. Все, что он делает, это рисует DoubleBufferImage
, хотя на самом деле он должен читать g.drawImage(DoubleBufferImage, 0, 0, this);
Итак, что все это делает?
По сути, это необдуманная попытка выполнить двойную буферизацию в Swing ... которая по умолчанию уже имеет двойную буферизацию.
Однако, как вы можете видеть из рендера, они использовали графику для рисования. Но все ли это нарисовано в DoubleBufferImage? Экземпляр изображения похож на экземпляр панели?
Нет. Компонент - это объект, который имеет ряд свойств. Одна из его задач - рисовать его состояние, что выполняется с помощью различных методов рисования, которым передается контекст Graphics
, который присоединяется к нативному узлу и в конечном итоге будет отображаться на экране (или принтере).
A BufferedImage
- это просто изображение. Контекст Graphics
- это просто простое средство рисования. Затем он может быть сохранен в файл или, как в данном случае, нарисован в контексте компонента (через Graphics
).
Как я уже говорил выше, Graphics
- это просто абстрактный слой, который позволяет вам выполнять операции рисования для множества различных мест назначения, экрана, принтеров, изображений и т. Д. *
Я имею в виду, это просто добавляется к кадру?
Нет. Это не компонентный класс
Поскольку это система двойного буферизации, я хочу знать, какие методы рисуют напрямую, а какой - метод, который рисует заранее.
paintComponent
и (опрометчивый) paintScreen
рисуют изображение непосредственно в компонент, который в конечном итоге будет отображаться на экране подсистемой рисования.
Дальнейшее чтение ...