I have a jpanel that I draw on. I would like to be able to zoom in and out using the mousewheel, but I want to zoom to the location of the mouse, such that the point under the mouse stays the same. I have found some questions here on stackoverflow, but they did not work for me.
I got pretty close to doing what I want by implementing what is described here. Here is my code:
public class MyPanel extends JPanel {
...
private double zoom = 1;
private double zoom_old = 1;
private int zoomPointX;
private int zoomPointY;
...
class CustomMouseWheelListener implements MouseWheelListener {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
zoomPointX = e.getX();
zoomPointY = e.getY();
if (e.getPreciseWheelRotation() < 0) {
zoom -= 0.1;
} else {
zoom += 0.1;
}
if (zoom < 0.01) {
zoom = 0.01;
}
repaint();
}
}
...
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
if (zoom != zoom_old) {
double scalechange = zoom - zoom_old;
zoom_old = zoom;
double offsetX = -(zoomPointX * scalechange);
double offsetY = -(zoomPointY * scalechange) ;
AffineTransform at = new AffineTransform();
at.scale(zoom, zoom);
at.translate(offsetX, offsetY);
g2D.setTransform(at);
}
a_different_class_where_i_do_some_drawing.draw(g2D);
}
}
This ALMOST does what I want. If I try to zoom, I notice that the position of the mouse is taken into account, so for example If I have my mouse on the left of the panel it will roughly zoom in on the left. However, it does not zoom exactly onto the mouse, so the point under the mouse still changes.
Can anyone help me fix this?
EDIT: Here is a picture of what is happening with the code posted above: I start out with the mouse on the blue square and then just scroll with the mouse wheel. As you can see, the mouse position if being changed:
I solved the problem by implementing what is being described here
Here is the updated code:
public class MyPanel extends JPanel {
...
private double zoom = 1;
private int zoomPointX;
private int zoomPointY;
...
class CustomMouseWheelListener implements MouseWheelListener {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
zoomPointX = e.getX();
zoomPointY = e.getY();
if (e.getPreciseWheelRotation() < 0) {
zoom -= 0.1;
} else {
zoom += 0.1;
}
if (zoom < 0.01) {
zoom = 0.01;
}
repaint();
}
}
...
protected void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
super.paintComponent(g2D);
AffineTransform at = g2D.getTransform();
at.translate(zoomPointX, zoomPointY);
at.scale(zoom, zoom);
at.translate(-zoomPointX, -zoomPointY);
g2D.setTransform(at);
a_different_class_where_i_do_some_drawing.draw(g2D);
}
}