JPanel мерцает с помощью метода mouseMoved

У меня есть простой JPanel, который я использую для отображения изображения. Мне нужна какая-то функциональность, где я могу панорамировать изображение, перетаскивая его. У меня есть что-то вроде этого (обратите внимание, что код, который у меня есть, компилируется и работает правильно; приведенный ниже код сильно усечен, чтобы просто понять, что я делаю):

public class Data2DPanel extends JPanel { 
    public Data2DPanel(Data2D data) {
        // Set image
        this.image = Data2D.data2DToBufferedImage(data);

        // Set mouse listener
        Data2DMouseAdapter data2DMouseAdapter = new Data2DMouseAdapter();
        this.addMouseListener(data2DMouseAdapter);
        this.addMouseMotionListener(data2DMouseAdapter);
    }

    private class Data2DMouseAdapter extends MouseAdapter {
        @Override
        public void mouseDragged(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
                switch (actionState) {
                    case PAN:
                        xOffset = xOffsetInit + e.getX()-xPosInit;
                        yOffset = yOffsetInit + e.getY()-yPosInit;
                        paintComponent(getGraphics());
                        break;                                
                }
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

        // Paint image
        g2.drawImage(image,x,y,width,height,this);
        }
    }
}

Проблема в том, что много мерцания. Я проверил stackoverflow/google, и кажется, что многие проблемы с мерцанием связаны с тем, что люди переопределяют метод paint вместо метода paintComponent. Я также проверил isDoubleBuffered, и он возвращает true. Интуитивно я чувствую, что, возможно, метод mouseDragged обновляется слишком часто, чтобы paintComponent() не отставал, но я решил, что двойная буферизация все равно должна предотвращать мерцание. Мой вопрос в том, есть ли что-то неправильное в этом подходе и есть ли стандартное или элегантное решение для этого.


person Justin    schedule 09.09.2014    source источник
comment
paintComponent(getGraphics()); ‹- Вы имеете в виду repaint()?   -  person Paul Samsotha    schedule 09.09.2014
comment
@peeskillet Ваше предложение сработало! Вы можете опубликовать это как ответ. Я ищу его прямо сейчас, но не могли бы вы также дать краткое объяснение, почему следует вызывать repaint() вместо прямого вызова paintComponent()?   -  person Justin    schedule 09.09.2014


Ответы (1)


paintComponent(getGraphics()); должно быть repaint(). Сложные проблемы.

  1. Вы никогда не захотите звонить getGraphics() для индивидуальной окраски. Единственный объект Graphics, используемый для рисования, должен быть предоставлен в методе рисования.
  2. Вы никогда не должны вызывать paintXxx, чтобы попытаться "принудительно" перерисовать компонент. Вы должны вызвать repaint() и разрешить RepaintManager обрабатывать весь цикл обновления и покраски
person Paul Samsotha    schedule 09.09.2014