Я очень новичок в java.swing, и я просмотрел другие ответы, но я изо всех сил пытаюсь понять, как правильно удвоить буфер, чтобы удалить мерцание.
В настоящее время у меня есть класс JFrame с прослушивателем действий
JButton northWest = new JButton("↖");
northWest.setPreferredSize(new Dimension(60, 60));
moveBorder.add(northWest);
northWest.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainBoardJPanel mainBoardPanel = new MainBoardJPanel();
mainBoardPanel.movePlayer(painel.getGraphics(), -40, -40, playerInfo, currentPlayer.getUsername());
performMove();
}
});
При нажатии кнопки метод movePlayer (внутри класса MainBoardJPanel) рисует фон, значок игрока в новом месте и, наконец, еще один слой, который действует как туман войны.
public void movePlayer(Graphics g, int x, int y, PlayerInformation[] playerInfo, String username) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
try {
background = ImageIO.read(new File("Images\\BackgroundBoard.png"));
playerIcon1 = ImageIO.read(new File("Images\\PlayerIcon1.png"));
fogOfWar = ImageIO.read(new File("Images\\FogOfWar.png"));
} catch (Exception e) {
e.printStackTrace();
}
g.drawImage(background, 0, 0, this);
g.drawImage(playerIcon1, playerInfo[0].getPosX(), playerInfo[0].getPosY(), null);
int xFOW = x - 775;
int yFOW = y - 775;
g.drawImage(fogOfWar, xFOW, yFOW, this);
updateUserInfo(x, y, username);
setDoubleBuffered(true);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
(Это очень упрощенная версия, чтобы сократить нерелевантный код)
Поскольку каждое изображение рисуется последовательно, изображение продолжает мигать всякий раз, когда вызывается метод, как бы мне сделать двойную буферизацию?




but I'm struggling to understand how to properly double buffer in order to remove flickering
Я просто хочу прояснить одну вещь. Когда пользовательская раскраска выполнена правильно, компоненты Swing автоматически дважды буферизируются.
Вызов super.paint в movePlayer является неуместным злоупотреблением системой рисования.
Не используйте getGraphics, это не то, как работает индивидуальная раскраска. Кроме того, не удаляйте контекст Graphics, который вы не создавали, это может фактически помешать отрисовке компонентов, которые по расписанию будут отрисованы после того, как ваш.
Swing использует алгоритм пассивного рендеринга, это означает, что он будет планировать рисование, когда когда-либо решит, что это необходимо сделать. У вас нет контроля над этим, лучшее, что вы можете сделать, - это дать системе «подсказки», что вы хотели бы перерисовать компонент или какую-то часть компонента (например, repaint). Подсистема покраски затем решит, когда и что нужно красить. Вашим компонентам будет предложено выполнить операцию рисования с помощью их методов рисования.
Когда это сделано таким образом, Swing будет удваивать буферизацию операции рисования, поэтому все окрашенные компоненты буферизуются, и когда проход рисования завершен, изображение обновляется на экране.
Я очень рекомендую прочитать:
для получения более подробной информации о том, как работает система рисования в Swing и как вы должны с ней работать
В качестве побочного примечания я бы также избегал загрузки ресурсов (или выполнения каких-либо трудоемких задач) в любых функциях рисования. Покраска должна идти как можно быстрее
Большое спасибо, что многое проясняет, я внимательно прочитаю ссылки, данные спасибо!
1) Для более быстрой помощи опубликуйте минимальный воспроизводимый пример или Краткий, автономный, правильный пример. 2) Один из способов получить изображение (я) для примера - установить горячую ссылку на изображения в этот вопрос и ответ.