I have a simple JPanel
that I'm using to display an image. I want some functionality where I'm able to pan the image by dragging it. I have something like this (note the code I have compiles and runs properly; the code below is heavily truncated to just get an idea of what I'm doing):
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);
}
}
}
The problem is that there is a lot of flickering. I've checked stackoverflow/google and it seems a lot of the flickering problems are because people override the paint
method instead of the paintComponent
method. I've also checked isDoubleBuffered
and it returns true
. Intuitively, I feel maybe the mouseDragged
method is updating too much for paintComponent()
to keep up, but I figured double buffering should still prevent flickering from occuring. My question is if there's something inherently wrong with this approach and if there's a standard or elegant solution to this.
paintComponent(getGraphics());
should be repaint()
. Compounded problems.
getGraphics()
for custom painting. The only Graphics
object used to paint should be the one provided in the paint method.paintXxx
to try and "force" a repaint of the component. You should call repaint()
and allow the RepaintManager
to handle all the update and paint cycle