Как убрать мерцание с двойной буферизацией (java swing) - PullRequest
0 голосов
/ 06 июня 2018

Я очень новичок в java.swing, и я смотрел на другие ответы, но я пытаюсь понять, как правильно удвоить буфер для устранения мерцания.

В настоящее время у меня есть класс JFrame, которыйимеет действие Listener

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();
}

(Это очень упрощенная версия для сокращения нерелевантного кода)

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

1 Ответ

0 голосов
/ 06 июня 2018

но я изо всех сил пытаюсь понять, как правильно удвоить буфер для устранения мерцания

Я просто хочу сделать одну вещь очень ясно.Когда пользовательское рисование выполнено правильно, компоненты Swing автоматически получают двойную буферизацию.

Вызов super.paint in movePlayer является неуместным злоупотреблением системой рисования.

Не использовать getGraphicsЭто не так, как обычай рисовать.Кроме того, не избавляйтесь от контекста Graphics, который вы не создавали, это фактически может помешать компонентам, которые запланированы для рисования после того, как ваш нарисован.

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

Когда это будет сделано, Swing дважды буферизует операцию рисования, поэтому все окрашенные компоненты буферизуются, и когда прохождение рисования завершено,изображение обновляется до экрана

Я бы настоятельно рекомендовал прочитать:

для получения более подробной информации о том, как система рисования работает в Swing и как вы будете работать с ней

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

...